OI选手常见作死错误列表

给自己留一个备忘录。(同时说明了开-Wall的重要性)

1.赋值运算符与等于号不分

//使用-Wall编译选项会出现警告
if(n=1)puts("Yes");//此处应为n==1
else puts("No");

2.循环变量错误

for(int i=1;i<=n;i++)
 for(int j=1;j<=n;i++)//显然应该是j++
  //do something
for(int i=1;i<=n;i++)
 for(int j=n;j>=1;j++)//显然应该是j--
  //do something

3.运算符优先级问题

int a=num<<2+1;//这里会被解读为num<<(2+1)
a=(num<<2)+1;

4.多组数据下未初始化变量&&局部变量未赋初值

//比较好的习惯是将变量定义在循环内,从而求解每组数据时都能初始化变量
#include <stdio.h>
int sum;
int main()
{
 int T;
 scanf("%d",&T);
 while(T--)
 {
  //int sum=0;
  //像上面这样定义变量就不会出事了
  int n;
  scanf("%d",&n);
  for(int i=1;i<=n;i++)
  {
   int num;
   scanf("%d",&num);
   sum+=num;
  }
  printf("%d\n",sum);
 }
 return 0;
}
//NOIP2016 普及组 T1
//就是因为这个,本蒟蒻当时没拿到一等奖
#include <cstdio>
#include <algorithm>
#include <cmath>
using namespace std;
struct pencil
{
 int shuliang,jiage;
}a[5];
int main()
{
 //freopen("pencil.in","r",stdin);
 //freopen("pencil.out","w",stdout);
 int n,ans;//ans没有初始化,损失惨重
 //打开-Wall会发出警告
 scanf("%d",&n);
 for(int i=1;i<=3;i++)
 {
  scanf("%d%d",&a[i].shuliang,&a[i].jiage);
  ans=min(ans,(int)ceil(n*1.0/a[i].shuliang)*a[i].jiage);
 }
 printf("%d",ans);
 //fclose(stdin);
 //fclose(stdout);
 return 0;
}

5.边界判断&&特判

//导弹拦截连n^2的100分都没拿到手的代码
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#define maxn 100005
using namespace std;
int n,f[maxn],a[maxn],ans,s[255];
int main()
{
 int n=1;
 while(~scanf("%d",&a[n]))
  n++;
 n--;
 for(int i=1;i<=n;i++)
  f[i]=1;
 for(int i=1;i<=n;i++)
  for(int j=1;j<i;j++)
   if(a[j]>a[i])f[i]=max(f[j]+1,f[i]);//这里求解的可是最长不上升子序列啊,所以是>=号
 for(int i=1;i<=n;i++)
  ans=max(f[i],ans);
 printf("%d\n",ans);
 ans=0;
 for(int i=1;i<=n;i++)
  f[i]=1;
 for(int i=1;i<=n;i++)
  for(int j=1;j<i;j++)
   if(a[j]<a[i])f[i]=max(f[j]+1,f[i]);
 for(int i=1;i<=n;i++)
  ans=max(f[i],ans);
 printf("%d",ans);
 return 0;
}

6.我的输出去哪了?

#include <iostream>
#include <cstdio>
using namespace std;
int main()
{
 freopen("a.out","w",stdout);
 ios::sync_with_stdio(false);
 cout<<1;//正确的写法是cout<<1<<endl;
 //在关闭与stdio的同步后,一定在每行输出结束时加上endl来刷新缓冲区
 //否则输出将无法立刻被写入输出文件
 //无论何时,每行输出都以换行符结尾都是一个好习惯(即使只有一行输出的时候也是)
 fclose(stdout);
 return 0;//缓冲区的内容将在缓冲区满或程序结束时才会输出,但这时已经无法写入文件了
}

7.错位输出

//这个例子将说明,关闭与stdio的同步后,混用两种IO的后果
//建议单步运行来观察效果
#include <iostream>
#include <cstdio>
using namespace std;
int main()
{
 ios::sync_with_stdio(false);
 //关闭IO后,cin/cout将使用独立缓冲区,而不是将输出同步至scanf/printf的缓冲区,从而减少IO耗时
 cout<<"a\n";
 //cout下,使用'\n'换行时,内容会被缓冲而不会被立刻输出,应该使用endl来换行并立刻刷新缓冲区
 printf("b\n");
 //printf的'\n'会刷新printf的缓冲区,导致输出错位
 cout<<"c\n";
 return 0;//程序结束时,cout的缓冲区才会被输出
}

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据