今天开始ACM训练,选择了刘汝佳的《挑战编程》,暂时算是开始了。
测评的网址:
http://www.programming-challenges.com
第一个题目是水题啦。3n+1。
也不用多久就水出来了,完全按着意思写就好了。代码也很随意。
其实我一开始就写对,知识提交方式写错了,楞是想不出来为什么,再交一次就过了。
关键就是学会一点,不要乱假设,如果以为i,j有顺序,那么就明显A不出来(但是其实也不能直接排序,因为还要再输出。)
#include<iostream> using namespace std; int main(){ int i,j,a,p,q; while(cin>>i>>j){ p=i; q=j; if(i>j){ //swap a=i; i=j; j=a; } int maxC=0; for(int k=i;k<=j;k++){ a=k; int count=1; while(a!=1){ if(a%2==0) a/=2; else a=a*3+1; count++; } if(count>maxC) maxC=count; } cout<<p<<" "<<q<<" "<<maxC<<endl; } return 0; }
第二题,是说扫雷,又是一条水题,一看就知道怎么做了。而且明显不需要考虑时间的问题,才是100*100的最坏情形。
但是,一开始我想了以下在边缘的越界怎么办,后来,想起我写的山寨消灭星星,就是采用浪费边缘数组的策略,避免判断。
之后,图书馆的书真坑爹,书的上一位借读者,写了一句“注意最后一行没有空格”。我就把要求的“空行”看成“空格”了。
巨坑爹,直到我看了原题。一个小错误都误人子弟啊。我提交了三次。第一次是忘记Field #。第二次就是所谓的“空格”问题。
#include<iostream> #include"string.h" using namespace std; #define N 110 int a[N][N]; void add(int i,int j){ if(a[i][j]>=0) a[i][j]++; } int main(){ int n,m,i,j; char tmp; int first=0; while(cin>>n>>m&&(n||m)){ memset(a,0,sizeof(a)); //从1,1开始。避免越界 for(i=1;i<=n;i++) for( j=1;j<=m;j++){ cin>>tmp; if(tmp=='*'){ a[i][j]=-1; for(int k=-1;k<2;k++) for(int l=-1;l<2;l++) if(k!=0||l!=0) add(i+k,j+l); } } if(first!=0){ cout<<endl; } first++; //print cout<<"Field #"<<first<<":\n"; for(i=1;i<=n;i++){ for( j=1;j<=m;j++){ if(a[i][j]>=0) cout<<a[i][j]; else cout<<"*"; } cout<<endl; } } return 0; }
第三道题是The trip.一开始我以为是贪心算法,但是看真一点,这只是一条平均数的题目。看了别人的解释就明白怎么做了。
其实也没有很麻烦,主要是“可以容许一分的差距”,让我看了很久。
#include<iostream> using namespace std; #define N 1020 double s[N]; int main(){ int n,i; while(cin>>n&&n){ double res1=0,res2=0,sum=0; for( i=0;i<n;i++){ cin>>s[i]; sum+=s[i]; } sum=(int)((sum/n)*100+0.5); sum=sum/100; for( i=0;i<n;i++){ if(s[i]<sum){ res1+=sum-s[i]; }else{ res2+=s[i]-sum; } } cout.precision(2); cout.setf(ios::fixed | ios::showpoint); cout << "$" ; if(res1>res2) cout<<res2; else{ cout<<res1; } cout<<endl; } return 0; }