寒假的ACM训练(一)

今天开始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;


}


你可能感兴趣的:(ACM)