A1046
【Notes】超时
题目地址
PAT (Advanced Level) Practice #1046 Shortest Distance
问题代码
【Notes】其实已经做过一次修改,将向另一个方向的距离改为用sum-d1来表示。
#include<cstdio>
const int maxn=100005;
int d[maxn]={0};
int main()
{
int n,m,sum=0;scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&d[i]);
sum+=d[i];
}
scanf("%d",&m);
for(int i=0;i<m;i++)
{
int maxx,a,b,temp,d1=0,d2=0;
scanf("%d%d",&a,&b);
if(a>b)
{
temp=a;
a=b;
b=temp;
}
for(int j=a;j<b;j++) d1+=d[j];
d2=sum-d1;
if(d1>=d2) maxx=d2;
else maxx=d1;
printf("%d\n",maxx);
}
return 0;
}
修改
以dis[i]
表示1号结点按顺时针方向到达“第i号结点顺时针方向的下一个结点”的距离。这样二者相减即可得到距离,时间复杂度为
O
(
1
)
O(1)
O(1)
#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn=100005;
int d[maxn]={0};
int dis[maxn]={0};
int main()
{
int n,m,sum=0;
int a,b,temp;//定义在for循环内会出错(原因?)
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&d[i]);
sum+=d[i];
dis[i]=sum;
}
scanf("%d",&m);
for(int i=0;i<m;i++)
{
//int a,b,temp;
scanf("%d%d",&a,&b);
/*
if(a>b)
{
temp=a;
a=b;
b=temp;
}*/
if(a>b) swap(a,b); //有可以直接用的swap函数
//for(int j=a;j<b;j++) d1+=d[j];
//d2=sum-d1;
//if(d1>=d2) maxx=d2;
//else maxx=d1;
temp=dis[b-1]-dis[a-1];
printf("%d\n",min(temp,sum-temp));
}
return 0;
}
A1065
【Notes】溢出问题
题目地址
PAT (Advanced Level) Practice #1065 A+B and C (64bit)
问题代码
【Notes】想得也太简单了= - =
#include<cstdio>
int main()
{
long long int a,b,c;
int n; scanf("%d",&n);
for(int i=0;i<n;i++)
{
scanf("%lld%lld%lld",&a,&b,&c);
if((a+b)>c) printf("Case #%d: true\n",i+1);
else printf("Case #%d: false\n",i+1);
}
return 0;
}
修改
- long long 的范围是 [ − 2 63 , 2 63 ) [-2^{63},2^{63}) [−263,263) 因此题目中的数字相加会导致溢出;
- 正数之和成负数,负数之和成整数则为溢出;
- 只需与0比较即可。
【情况分析】
-
A
+
B
≥
2
63
A+B\ge2^{63}
A+B≥263显然
A
+
B
>
C
A+B>C
A+B>C成立;但会发生正溢出,由题目条件,
A
+
B
A+B
A+B最大为
2
64
−
2
2^{64}-2
264−2因此使用long long溢出后值的区间为
[
−
2
63
,
−
2
]
[-2^{63},-2]
[−263,−2]
(由 ( 2 64 − 2 ) % ( 2 64 ) = − 2 (2^{64}-2)\%(2^{64})=-2 (264−2)%(264)=−2计算得出)。# 涉及计组吗 - A + B < − 2 63 A+B<-2^{63} A+B<−263显然 A + B < C A+B<C A+B<C成立;但会发生负溢出。同上,负溢出后值的区间为 [ 0 , 2 63 ) [0,2^{63}) [0,263)(由 ( − 2 64 ) % ( 2 64 ) = 0 (-2^{64})\%(2^{64})=0 (−264)%(264)=0计算得出)
- 无溢出的情况正常比较即可。
#include<cstdio>
int main()
{
int T, tcase=1;
scanf("%d",&T);
while(T--)
{
long long a,b,c;
scanf("%lld%lld%lld",&a,&b,&c);
long long res = a+b;
bool flag;
if(a>0&&b>0&&res<0) flag = true;//判断是否正溢出
else if(a<0&&b<0&&res>=0) flag=false;
else if(res>c) flag=true;
else flag=false;
if(flag==true) printf("Case #%d: true\n",tcase++);
else printf("Case #%d: false\n",tcase++);
}
return 0;
}
B1010
【Notes】输入问题、输出格式
题目地址
PAT (Basic Level) Practice #1010 多项式求导
问题代码
- 如何输入
- 如何防止末尾空格
- 零多项式什么意思
#include<cstdio>
const int maxn = 1000;
int main()
{
int a[maxn]={0},b[maxn]={0};
int m,n;
while(scanf("%d%d",&m,&n)!=EOF)
{
if(n)
{
printf("%d %d",m*n,n-1);
printf(" ");
}
}
return 0;
}
修改
- 输入:while…EOF的使用
- 输出:用一个变量来计数即可控制空格
#include<cstdio>
int main()
{
int m,n,cnt=0;
while(scanf("%d%d",&m,&n)!=EOF)
{
if(m&&n)
{
if(cnt!=0) printf(" ");
printf("%d %d",m*n,n-1);
cnt++;
}
}
if(cnt==0) printf("0 0");
return 0;
}
A1002
题目地址
PAT (Advanced Level) Practice #1002 A+B for Polynomials
问题代码
【Notes】Wrong Answer
//2.4x+3.2
//1.5x^2+0.5x
//1.5x^2+
#include<cstdio>
#include<algorithm>
using namespace std;
struct node
{
int n;
float a;
};
node item1[11];
node item2[11];
node item[11];
int main()
{
int k1,k2,cnt=0;
scanf("%d",&k1);
for(int i=0;i<k1;i++)
scanf("%d%f",&item1[i].n,&item1[i].a);
scanf("%d",&k2);
for(int i=0;i<k2;i++)
scanf("%d%f",&item2[i].n,&item2[i].a);
int dk=max(k1,k2);
int sk=min(k1,k2);
int t=0,i=0,j=0;
while(1)
{
if((j==k2)&&(i!=k1))
{
item[t].n=item1[i].n;
item[t].a=item1[i].a;
t++;
i++;
continue;
}
if((i==k1)&&(j!=k2))
{
item[t].n=item2[j].n;
item[t].a=item2[j].a;
t++;
j++;
continue;
}
if((i==k1)&&(j==k2)) break;
if(item1[i].n<item2[j].n)
{
item[t].n=item2[j].n;
item[t].a=item2[j].a;
t++;
j++;
}
else if(item1[i].n==item2[j].n)
{
item[t].n=item1[i].n;
item[t].a=item1[i].a+item2[j].a;
t++; i++;j++;
}
else if(item1[i].n>item2[j].n)
{
item[t].n=item1[i].n;
item[t].a=item1[i].a;
t++;
i++;
}
}
printf("%d ",t);
for(int k=0;k<t;k++)
{
printf("%d %.1f",item[k].n,item[k].a);
if(k!=t-1) printf(" ");
}
}
【问题】 待查找。。
修改
思路:用数组a[i]记录指数为i的项的系数即可。
#include<cstdio>
const int maxn=1005;
double a[maxn]={0.0};
double b[maxn]={0.0};
double c[maxn]={0.0};
int main()
{
int n1,n2,e,cnt=0;
double k;
scanf("%d",&n1);
for(int i=0;i<n1;i++)
{
scanf("%d%lf",&e,&k);
a[e]=k;
}
scanf("%d",&n2);
for(int i=0;i<n2;i++)
{
scanf("%d%lf",&e,&k);
b[e]=k;
}
for(int i=0;i<1001;i++)
{
c[i]=a[i]+b[i];
if(c[i]!=0) cnt++;
}
printf("%d",cnt);
for(int i=1000;i>=0;i--)
{
if(c[i]!=0)
{
if(cnt) printf(" ");
printf("%d %.1f",i,c[i]);
cnt--;
}
}
return 0;
}
A1009
【Notes】与上题思路相同,但要注意开的数组的大小。因为两个输入的最高次项为1000,所以结果数组开的大小应该至少为2001。
题目地址
PAT (Advanced Level) Practice #1009 Product of Polynomials
代码
#include<cstdio>
const int maxn=2001;
double a[maxn]={0.0};
double b[maxn]={0.0};
double c[maxn]={0.0};
int main()
{
int n1,n2,e,cnt=0;
double k;
scanf("%d",&n1);
for(int i=0;i<n1;i++)
{
scanf("%d%lf",&e,&k);
a[e]=k;
}
scanf("%d",&n2);
for(int i=0;i<n2;i++)
{
scanf("%d%lf",&e,&k);
b[e]=k;
}
for(int i=0;i<1001;i++)
{
for(int j=0;j<1001;j++)
{
c[i+j]+=a[i]*b[j];
}
}
for(int i=0;i<2001;i++) if(c[i]!=0) cnt++;
printf("%d",cnt);
for(int i=2000;i>=0;i--)
{
if(c[i]!=0)
{
if(cnt) printf(" ");
printf("%d %.1f",i,c[i]);
cnt--;
}
}
return 0;
}