P1496火烧赤壁
题目:
曹操平定北方以后,公元 208 年,率领大军南下,进攻刘表。他的人马还没有到荆州,刘表已经病死。他的儿子刘琮听到曹军声势浩大,吓破了胆,先派人求降了。
孙权任命周瑜为都督,拨给他三万水军,叫他同刘备协力抵抗曹操。
隆冬的十一月,天气突然回暖,刮起了东南风。
没想到东吴船队离开北岸大约二里距离,前面十条大船突然同时起火。火借风势,风助火威。十条火船,好比十条火龙一样,闯进曹军水寨。那里的船舰,都挤在一起,又躲不开,很快地都烧起来。一眨眼工夫,已经烧成一片火海。
曹操气急败坏的把你找来,要你钻入火海把连环线上着火的船只的长度统计出来!
输入格式
第一行一个整数 N。
以后 N 行,每行两个数:A[i], B[i],表示连环线上着火船只的起始位置和终点。
输出格式
输出着火船只的总长度。保证答案在 32 位带符号整数的表示范围内。
输入输出样例
输入#1:
3
-1 1
5 11
2 9
输出#1:
11
说明/提示
0<n<20000 -2147483648<a[i],b[i]<2147483648
————————————下面开始解析—————————————
方法一:
这道题如果没有负数
就会很简单
扫描二维码关注公众号,回复:
9596715 查看本文章
每次输入两个数
把bool数组从f[a[i]]到f[b[i]]
全部赋值为1
(初始值为0)
如果有负数
就再设一个数组
用来处理负数
下面附上1.0代码
#include<bits/stdc++.h>
#include<iostream>
#include<cstdlib>
#include<cstdio>
using namespace std;
struct cina
{
int a;
int b;
};
cina c[10001];
int n,sum,zd[1000001],fd[1000001];
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
cin>>c[i].a>>c[i].b;
for(int i=1;i<=n;i++)
{
if(c[i].a<0)
{
if(c[i].b<0)
{
for(int j=c[i].a;j<=c[i].b;j++)
{
if(fd[-j]!=0)
{
fd[-j]=0;
sum++;
}
}
}//如果这一段都是负数
else
{
for(int j=c[i].a;j<=-1;j++)
{
if(fd[-j]!=0)
{
fd[-j]=0;
sum++;
}
}
for(int j=0;j<=c[i].b;j++)
{
if(zd[j]!=0)
{
zd[j]=0;
sum++;
}
}
}//如果前一段是负数,后一段是正数
}
else
{
for(int j=c[i].a;j<=c[i].b;j++)
{
if(zd[j]!=0)
{
zd[j]=0;
sum++;
}
}
}//这一段都是正数
}
cout<<sum<<endl;
return 0;
}
但是
这道题数据范围很大
数组开不了太大
所以
这个方法
不靠谱!
方法2:
输入进来后
所有的变量先排序
接着分成以下三种方案:
1、如果a[i]小于b[i-1]并且b[i]大于b[i-1]
ans+=b[i]-b[i-1];
2、如果a[i]和b[i]都小于b[i-1]
ans不变
3、如果a[i]和b[i]都大于b[i-1]
ans+=b[i]-a[i]
下面是2.0代码
#include<bits/stdc++.h>
#include<iostream>
#include<cstdlib>
#include<cstdio>
using namespace std;
int n,a[20001],b[20001],sum,temp,R;
//bool flag=true;
int main()
{
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i]>>b[i];
for(int i=1;i<=n-1;i++)
{
for(int j=1;j<=n-i;j++)
{
if(a[j]>a[j+1])
{
temp=a[j];
a[j]=a[j+1];
a[j+1]=temp;
temp=b[j];
b[j]=b[j+1];
b[j+1]=temp;//b数组也要变
}
}
}//排序
//for(int i=1;i<=n;i++) cout<<a[i]<<" "<<b[i]<<endl;
sum=b[1]-a[1];
R=b[1];
if(n==1)
{
cout<<sum<<endl;
return 0;
}
for(int i=2;i<=n;i++)
{
if(a[i]<R)
{
if(b[i]<=R) continue;//方案2
else
{
sum+=b[i]-R;
R=b[i];
continue;
}//方案1
}
else
{
sum+=b[i]-a[i];
R=b[i];
}//方案3
}
cout<<sum<<endl;
return 0;
}
你会发现
第一个测试点
超时了
解决的方法是
将冒泡排序改成选择排序
下面是3.0代码
#include<bits/stdc++.h>
#include<iostream>
#include<cstdlib>
#include<cstdio>
using namespace std;
int n,a[20001],b[20001],sum,temp,R;
bool flag=true;
int main()
{
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i]>>b[i];
for (int i=1;i<=n-1;i++)
{
int k=i;
for(int j=i+1;j<=n;j++)
if(a[j]<a[k]) k=j;
if(k!=i)
{
temp = a[i];
a[i] = a[k];
a[k] = temp;
temp=b[i];
b[i]=b[k];
b[k]=temp;
}
}//改成了选择排序
sum=b[1]-a[1];
R=b[1];
if(n==1)
{
cout<<sum<<endl;
return 0;
}
for(int i=2;i<=n;i++)
{
if(a[i]<R)
{
if(b[i]<=R)
continue;
else
{
sum+=b[i]-R;
R=b[i];
continue;
}
}
else
{
sum+=b[i]-a[i];
R=b[i];
}
}
cout<<sum<<endl;
return 0;
}