A - FatMouse' Trade
该题就是,简单的一个贪心的问题,求最大金额的数目,只需要sort排序就可以了。
代码如下:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
struct node
{
int m;
int n;
};
bool cmp(node n,node m)
{
return n.n*1.0/n.m>m.n*1.0/m.m;
}
struct node a[1010];
int n;
int m;
int main()
{
while(scanf("%d%d",&n,&m)!=EOF)
{
if(n<0 && m<0) break;
for(int i=0;i<m;i++)
{
scanf("%d%d",&a[i].n,&a[i].m);
}
sort(a,a+m,cmp);
double sum = 0;
for(int i=0;i<m;i++){
if(n>=a[i].m){
n = n-a[i].m;
sum+=a[i].n;
}else{
sum+=n*(a[i].n*1.0/a[i].m);
break;
}
}
printf("%.3f\n",sum);
}
return 0;
}
B - Fire Net
该题求放炮塔,最多能放多少个?炮塔四面都可以开炮,所以不能面对着炮塔。如果有中间应该有一个墙、去阻隔它的炮弹。采用广度优先搜索(DFS)。
代码如下:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
char map[10][10];
int n,xx,yy;
int flag=0;
int ans=0;
//判断是不是可以放
bool cmp(int x,int y)
{
for(int i=x-1;i>=1;i--)
{
if(map[i][y]=='#')
return false;
if(map[i][y]=='X')
break;
}
for(int i=y-1;i>=1;i--)
{
if(map[x][i]=='#')
return false;
if(map[x][i]=='X')
break;
}
return true;
}
//递归寻找
int DFS(int x,int y,int z)
{
if(y==n+1){
x++;
y=1;
}
if(x==n+1 && y==1)
{
// print();
if(ans < z)
ans = z;
return z;
}
if(flag) return z;
if(map[x][y]=='.' && cmp(x,y))
{
map[x][y]='#';
DFS(x,y+1,z+1);
map[x][y]= '.';
}
DFS(x,y+1,z);
}
int main()
{
while(scanf("%d",&n),n)
{
ans=0;
xx = yy =1;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
cin>>map[i][j];
}
}
DFS(xx,yy,0);
printf("%d\n",ans);
}
return 0;
}
C - Climbing Worm
该题指的是爬虫爬墙的问题,每天爬一点,之后又会掉下去一点,每一次要一分钟。求至少多少分钟爬到井口。
注意在第一次爬,和最后一次的爬,就可以了。
代码如下:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
int main()
{
int x,y,z;
while(scanf("%d%d%d",&x,&y,&z)!=EOF)
{
if(x==y && y==z && y==0)
break;
int score = 0;
while(true){
if(score!=0){
x+=z;
x-=y;
score+=2;
}else{
x-=y;
score++;
}
if(x<=0) break;
}
printf("%d\n",score);
}
return 0;
}
D - Moving Tables
该题讲的是搬房子,在某一个人搬房子的时候,他所占用的街道,别人是不能用的。我们主要注意在像2 3,从2搬3的这样的数据的时候,前者为偶数,或者后者为奇数的时候,他们所占用的街道范围,其实是偶数-1,或者奇数加一,的范围。如上面的2到3,其实可以看做1到4都被占用了。只要在数据输入的时候,改变一下就可以了。还有数据可能前者大于后者,例如3到2.指从3搬到2.
从而该题变成了求范围的类型的题目。
///该代码,主要是先求可以一起搬的房子,无冲突的,
///之后求有冲突的,也就是自己在搬的时候,别人不能搬的那种,
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std;
struct app{
int kai;
int jie;
int k;
}a[401];
bool cmp(app a,app b)
{
if(a.kai!=b.kai)
return a.kai<b.kai;
return a.jie<b.jie;
}
int main()
{
int n,m;
scanf("%d",&n);
while(n--)
{
memset(a,0,sizeof(a));
scanf("%d",&m);
for(int i=0;i<m;i++)
{
scanf("%d%d",&a[i].kai,&a[i].jie);
if(a[i].kai%2==0) a[i].kai--;
if(a[i].jie%2!=0) a[i].jie++;
if(a[i].kai>a[i].jie)
swap(a[i].kai,a[i].jie);
}
sort(a,a+m,cmp);
int ans =0;
for(int i=0;i<m;i++)
{
if(a[i].k==1) continue;
int max = a[i].kai;
int min = a[i].jie;
int q = 0;
for(int j=i+1;j<m;j++)
{
if( (min<a[j].kai || max>a[j].jie) && a[j].k==0)
{
max = a[j].kai;
min = a[j].jie;
a[j].k = 1;
if(q==0)
{
ans+=10; //他们可以一起搬,就记录时间10分钟。
a[i].k=1;
q=1;
}
}
}
}
for(int i=0;i<m;i++)
{
if(a[i].k==0){
ans+=10; //他们只能自己搬,不能和别人一起搬的。
}
}
printf("%d\n",ans);
}
return 0;
}
E - Wooden Sticks
该题就是讲加工木头的问题,突破点就是在:看一组数据, n1,m1,n2,m2,如果n1<=n2&&m1<=m2他们可以一起加工,时间为单个加工时间。所以我们只要排序一下,按照n1从小到大,n1相等,m1也从小到大的顺序排序就可以了。
///该代码,主要是先求可以一起加工的木头
///之后自己在加工的时候,别人不能和你一起加工的那种,
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
struct node
{
int n,m,k;
}a[10005];
bool cmp(node n,node m)
{
if(n.n!=m.n)
{
return n.n<m.n;
}
return n.m<m.m;
}
int main()
{
int n;
int m;
scanf("%d",&n);
while(n--)
{
scanf("%d",&m);
memset(a,0,sizeof(a));
for(int i=0;i<m;i++)
{
scanf("%d%d",&a[i].n,&a[i].m);
}
sort(a,a+m,cmp);
int ans =0;
for(int i=0;i<m;i++)
{
if(a[i].k==1) continue;
int max = a[i].n;
int min = a[i].m;
int q = 0;
for(int j=i+1;j<m;j++)
{
if(max<=a[j].n && min<=a[j].m && a[j].k==0)
{
max = a[j].n;
min = a[j].m;
a[j].k = 1;
if(q==0)
{
ans++;
a[i].k=1;
q=1;
}
}
}
}
for(int i=0;i<m;i++)
{
if(a[i].k==0){
ans++;
}
}
printf("%d\n",ans);
}
return 0;
}
F - Tian Ji -- The Horse Racing
该题,就是田忌赛马,我们知道一点就可以了,无论怎么样我们都要用最不好的马,去减少国王最好的马,即使最不好的马之间相同,我们也要减少国王最好的马,除非田忌赢了,否则不好的马,就去抵消国王最好的马,最好的马比不过我们也去减少最不好的马,从而抵消掉。
代码如下:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int main()
{
int a[1000];
int n;
int b[1000];
int i,s,j,e,sum;
while(scanf("%d",&n)!=EOF)
{
if(n==0) break;
for( i=0; i<n; i++)
scanf("%d",&a[i]);
for( i=0; i<n; i++)
scanf("%d",&b[i]);
sort(a,a+n);
sort(b,b+n);
i=s=0;
j=e=n-1;
sum=0;
while(i<=j)
{
if(a[i]>b[s])
{
sum++;
s++;
i++;
}
else if(a[i]<b[s])
{
sum--;
e--;
i++;
}
else
{
if(a[j]>b[e])
{
sum++;
e--;
j--;
}
else
{
if(a[i]<b[e])
sum--;
e--;
i++;
}
}
}
printf("%d\n",sum*200);
}
return 0;
}
G - 最少拦截系统
该题,就是把导弹拦截下来,用最少的系统数目,我们用一个数组去存每一个拦截系统的下限。如果你低于下限,那么你就被拦截,不然就加一个系统。就可以了。把之前的遍历一边就ok了。
代码如下:
#include <iostream>
#include <string.h>
using namespace std;
int dao[1004];
int main()
{
int n;
int height;
int i,j;
while(cin>>n)
{
memset(dao,0,sizeof(dao));
int num=1;
cin>>dao[1];
for(i=2;i<=n;i++)
{
cin>>height;
for(j=1;j<=i;j++)
{
if(height<=dao[j])
{
dao[j]=height;
break;
}
}
if(j>i) ///需要加一个系统区拦截。
dao[num++]=height;
}
cout<<num<<endl;
}
return 0;
}
H - Flying to the Mars
就是求相同非负整数出现的最多数目,你用一个int数组去存起来就可以了,可以去做,也可以用一个map去做也就。
代码如下:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<map>
using namespace std;
int main()
{
int n;
while(scanf("%d",&n)!=EOF)
{
int s;
map<int,int>a;
a.clear();
int max =0;
for(int i=0;i<n;i++)
{
scanf("%d",&s);
a[s]++;
if(a[s]>max) max = a[s];
}
printf("%d\n",max);
}
return 0;
}
I - 今年暑假不AC
该题就是求能看完整节目的数目。简单的贪心思想。
代码如下:
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
struct node
{
int x,y;
}a[10010];
bool cmp(node n,node m)
{
return n.y<m.y;
}
int main(){
int n;
while(scanf("%d",&n),n)
{
for(int i=0;i<n;i++)
scanf("%d%d",&a[i].x,&a[i].y);
sort(a,a+n,cmp);
int kai = 0;
int jie = 0;
for(int i=0;i<n;i++)
{
if(kai<=a[i].x)
{
kai = a[i].y;
jie++;
}
}
printf("%d\n",jie);
}
return 0;
}
J - 多项式求和
水题。
代码如下:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
int main()
{
int n;
while(scanf("%d",&n)!=EOF)
{
int m;
for(int j=0;j<n;j++){
scanf("%d",&m);
double sum = 0;
for(int i=1;i<=m;i++)
{
if(i%2==0) sum-=1.0/i;
else sum+=1.0/i;
}
printf("%.2f\n",sum);
}
}
return 0;
}
K - Repair the Wall
水题。
代码如下:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
bool cmp(int n,int m)
{
return n>m;
}
int k[600];
int main(){
int n,m;
double sum ;
int q = 0;
while(scanf("%d%d",&n,&m)!=EOF)
{
q=0;
sum =0;
memset(k,0,sizeof(k));
for(int i=0;i<m;i++)
scanf("%d",&k[i]);
sort(k,k+m,cmp);
for(int i=0;i<m && q==0;i++)
{
sum+=k[i];
if(sum>=n)
{
printf("%d\n",i+1);
q=1;
}
}
if(q==0) printf("impossible\n");
}
return 0;
}
L - 悼念512汶川大地震遇难同胞——老人是真饿了
详细解答:http://blog.csdn.net/zjwsa/article/details/74941097
代码如下:
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cmath>
#include<cstring>
using namespace std;
struct node
{
int x,y;
}a[10005];
bool cmp(node n,node m)
{
return n.x<m.x;
}
int main()
{
int n;
int i,j,k,t;
scanf("%d",&n);
int sum,num;
while(n--)
{
double q = 0;
memset(a,0,sizeof(a));
scanf("%d%d",&sum,&num);
for(i=0;i<num;i++)
scanf("%d%d",&a[i].x,&a[i].y);
sort(a,a+num,cmp);
for(i=0;i<num;i++)
{
if(sum>=a[i].x*a[i].y)
{
sum = sum - a[i].x*a[i].y;
q+=a[i].y;
}else{
q+=sum*1.0/a[i].x;
sum=-1;
}
if(sum<=0) break;
}
printf("%.2f\n",q);
}
return 0;
}
M - Filthy Rich
该题,讲的是从开始点到最后一点,你选择一条路径可以拿到最多的黄金。你只可以选择前进,下走,斜走。不可以后退,求最多的黄金数目。简单的动态规划,
代码如下:
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;
int map[1005][1005];
int dp[1005];
int x,y;
int main()
{
int n;
scanf("%d",&n);
int t=1;
while(n--)
{
scanf("%d%d",&x,&y);
memset(map,0,sizeof(map));
memset(dp,0,sizeof(dp));
for(int i=1;i<=x;i++)
{
for(int j=1;j<=y;j++)
{
scanf("%d",&map[i][j]);
}
}
for(int i=1;i<=x;i++)
{
for(int j=1;j<=y;j++)
{
if(i==1)
dp[j] = dp[j-1] + map[i][j];
else{
int max = dp[j-1]>dp[j]?dp[j-1]:dp[j];
dp[j] = max + map[i][j];
}
}
}
printf("Scenario #%d:\n",t++);
printf("%d\n\n",dp[y]);
}
return 0;
}
N - 迷瘴
简单排序一下,就可以了。用一个变量去判断存了一件物品的浓度和要求浓度比较,可以就存起来,存起来的数目加加,否则直接退出,因为后面的浓度比你更大,所以后面也就不需要加了。
代码如下:
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;
int a[105];
int main()
{
int n,z,v,w,i;
scanf("%d",&n);
while(n--){
scanf("%d%d%d",&z,&v,&w);
double sum;
for(i=0;i<z;i++)
scanf("%d",&a[i]);
sort(a,a+z);
if(a[0]>w){
printf("0 0.00\n");
}else{
sum=0;
double t;
int k=0;
for(i=0;i<z;i++)
{
sum+=a[i];
/// 加入你这种物品的浓度和要求浓度比较,
if(sum*1.0/(i+1)>w){
break;
}else{
t=sum;
}
///加入的物品数目。
k++;
}
printf("%d %.2f\n",k*v,t*1.0/k/100);
}
}
return 0;
}
O - Buy the Ticket
有时间,有思路再去写一下。主要就是太麻烦了。有时间就来更新一下。
P - Tri Tiling
该题,是一个递推公式,就是说,当他是奇数的时候,他是填不满的,因为会剩下一个1*1的方格。不信的话,你可以去试试,在此一点坑,0的时候是1.
代码如下:
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;
int main()
{
int n;
int a[31];
a[0] = 1;
a[1] = 0;
a[2] = 3;
a[3] = 0;
a[4] = 11;
for(int i=5;i<=30;i++)
{
a[i] = a[i-2]*4-a[i-4];
}
while(scanf("%d",&n)!=EOF)
{
if(n==-1) break;
if(n%2!=0) printf("0\n");
else{
printf("%d\n",a[n]);
}
}
return 0;
}
Q - 三角形
也是一个公式,因为一条边可以把区域分成2部分,而如果两条边相交于一点,就会把区域分成4个部分。两个三角形,一边相交就是4,也就是多产生了两条边,三角形有3条边,那就是用原来的加上多产生的,2+2*3就是8了。再去推理3个三角形,一边就是8,原来是4,多产生了4个。每一条边多产生4,三条边就是12.那也就是原来的8加上现在多产生的12,等于20.等等,我们再于几个三角形,挂上钩,因为我们是要得到一个递推公式,毕竟是电脑在处理。
1 2
2 8
3 20
拆一下,推来的公式,1的时候,为2,2的时候为2*3+2,3的时候为8+4*3,与n挂上钩就是。
所以我们就得出一个公式 a[i] = a[i-1]+2*3*(i-1);公式就是这样的,不信你们可以去推一下其他的a[i]去试一下,检验一下就可以了。
代码如下:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
int main()
{
int a[10001];
a[1] = 2;
for(int i=2;i<10001;i++)
{
a[i] = a[i-1]+6*(i-1);
}
int n;
scanf("%d",&n);
while(n--)
{
int m;
scanf("%d",&m);
printf("%d\n",a[m]);
}
return 0;
}
R - Let the Balloon Rise
该题,大意就是求相同颜色的最多的数量的那种颜色。解决就是采用一个map,就可以了。
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <map>
#include <string>
using namespace std;
int main()
{
string a,maxt;
map<string,int>s;
int n;
while(~scanf("%d",&n),n)
{
int max=0;
for(int i=0;i<n;i++)
{
cin>>a;
s[a]++;
if(max<s[a])
{
max=s[a];
maxt=a;
}
}
cout<<maxt<<endl;
}
return 0;
}
S - Number Sequence
该题,只要找出规律就可以了。由于它是以1和1开始的,所以我们只要找到那个连续的数字是1和1.就可以了
代码如下:
#include <stdio.h>
#include <string.h>
int s[50];
int main()
{
int a,b,n,i;
while(scanf("%d%d%d",&a,&b,&n),a || b || n)
{
int i;
s[0]=s[1]=1;
for(i = 2; i<50;i++)
{
s[i] = (a*s[i-1]+b*s[i-2])%7;
if(s[i] ==1 && s[i-1] == 1)
{break;}
}
n = n%(i-1);
if(n == 0)
printf("%d\n",s[i-2]);
else
printf("%d\n",s[n-1]);
}
return 0;
}
T - Elevator
详细解释,在此:http://blog.csdn.net/zjwsa/article/details/74910194
大致意思就是电梯,停止时间不算。只算一层位置到一层位置之间的时间。
代码如下:
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int main()
{
int n;
int a[100];
while(scanf("%d",&n)!=EOF)
{
if(n==0) break;
memset(a,0,sizeof(a));
a[0] = 0;
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
int time = 0;
for(int i=1;i<=n;i++)
{
if(a[i]-a[i-1]>0)
{
time +=(a[i]-a[i-1])*6+5;
}
else
{
time +=(a[i-1]-a[i])*4+5;
}
}
printf("%d\n",time);
}
return 0;
}
U - u Calculate e
该题就是输出各种的情况,就可以了。
代码如下:
#include<iostream>
#include<cstdio>
using namespace std;
int main()
{
printf("n e\n- -----------\n");
int k = 1,i,j;
double e= 0;
for(i = 0;i < 10;i ++)
{
k = 1;
for(j = 1; j <= i; j ++)
k *= j;
e += (double)1/k;
if(i <= 1)
printf("%d %.0f\n",i,e);
else if(i == 2)
printf("%d %.1f\n",i,e);
else
printf("%d %.9f\n",i,e);
}
}
V - Digital Roots
该题,很水,把数字每一位求和就可以了。注意就是第一次求和,还可能大于10.所以我们就不断的考虑,是不是小于10.
代码如下:
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int ans(int sum1)
{
int sum=0;
while(sum1>0)
{
int t = sum1%10;
sum+=t;
sum1 = sum1/10;
}
return sum;
}
int main()
{
char a[10005];
while(gets(a)!=NULL)
{
if(strlen(a)==1 && a[0]=='0') break;
int sum=0;
for(int i=0;i<strlen(a);i++){
sum+=a[i]-'0';
}
while(sum>=10)
{
sum = ans(sum);
}
cout<<sum<<endl;
}
return 0;
}
W - Uniform Generator
该题,就是求他按照那个公式不断求值,之后就是看重复了没,如果重复了,就退出。计算从开始到现在重复的数字之间出现了多少个数字。
代码如下:
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;
int f[100005];
int main()
{
int n,m;
int time;
while(scanf("%d%d",&n,&m)!=EOF)
{
memset(f,0,sizeof(f));
int sum = 0;
int q=0;
for(int i=0;i<m;i++)
{
sum = (sum+n)%m;
if(f[sum]==1) break;
else f[sum]=1;
}
time=0;
for(int i=0;i<m;i++)
{
if(f[i]==1) time++;
}
if(time==m) printf("%10d%10d Good Choice\n\n",n,m);
else printf("%10d%10d Bad Choice\n\n",n,m);
}
return 0;
}
X - A Mathematical Curiosity
该题,就是求满足公式的个数。
代码如下:
#include<iostream>
#include<cstdio>
using namespace std;
int main()
{
int n,m;
int t;
scanf("%d",&t);
while(t--)
{
int o = 1;
while(scanf("%d%d",&n,&m)!=EOF)
{
if(n==0 && m==0 ) break;
int ti = 0;
for(int i=1;i<n;i++)
{
for(int j=i+1;j<n;j++)
{
if((i*i+j*j+m)%(i*j)==0)
{
ti++;
}
}
}
printf("Case %d: %d\n",o++,ti);
}
if(t!=0){
cout<<endl;
}
}
return 0;
}
Y - Fibonacci Again
该题,主要就是找规律,就可以了。你可以去找1到80之间能被3整除的数字,找出规律,就是直接判断这个数字满不满足这个规律。
代码如下:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int a[2];
int main()
{
int n;
a[0]=1;
a[1]=1;
while(scanf("%d",&n)!=EOF)
{
int sum;
if(n<2){
sum = a[n];
}else{
sum = (n-2)%4;
}
if(!sum){
printf("yes\n");
}else{
printf("no\n");
}
}
return 0;
}
Z - Ignatius and the Princess III
这题,没有思路。等我有时间了,再去看看,然后更新一下。