2016-08-04
题源:http://acm.timus.ru/problemset.aspx?space=1&page=8
ctrl+f 搜索 Ural Regional School Programming Contest 2010
1.输入数字,输出对应区间的单词,如下图
输入的数字 | 输出 |
from 1 to 4 | few |
from 5 to 9 | several |
from 10 to 19 | pack |
from 20 to 49 | lots |
from 50 to 99 | horde |
from 100 to 249 | throng |
from 250 to 499 | swarm |
from 500 to 999 | zounds |
from 1000 | legion |
越是水的题,姿势越重要!!看姿势!!
代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <iostream> #include <cstring> #include <cstdio> using namespace std; int a[]={1,5,10,20,50,100,250,500,1000,2001}; char b[][8]={"few","several","pack","lots","horde","throng","swarm","zounds","legion"}; int main() { int n; cin>>n; for(int i=0;i<9;i++) { if(n>=a[i]&&n<a[i+1]) puts(b[i]); } return 0; }
2. 1786. Sandro's Biography
题目大意:给你一个字符串T,改其中的字符,使其中包含字符串S "Sandro";大写改成大写,小写改小写要花5毛钱,大小写互换再花5毛钱,问最少需要花多少钱可以成功?
思路:暴力吧~~~T和S头对齐,S串每次向右移动一位,计算需要花的钱,并用一个数sum记录,并更新最小值ans;最后输出ans即可。
代码:
#include <iostream> #include <cstdio> #include <cstring> using namespace std; char a[]="Sandro"; char b[201]; bool type(char b) //判断是否是小写 { return b>='a'&&b<='z'; } int value(char aa) //如果某个字符与'a'或'A'的差值, 是否可以大小写互换 { if(aa>='a') return aa-'a'; return aa-'A'; } int get(char aa,char bb) { if(aa==bb) return 0; if(type(aa)==type(bb)) return 5; if(value(aa)==value(bb)) return 5; //只需大小写互换 return 10; } int main() { while(~scanf("%s",b)) { int ans=0x3f3f3f3f; int lb=strlen(b); for(int i=0;i+5<lb;i++) { int sum=0; for(int j=0;j<6;j++) sum+=get(b[i+j],a[j]); //注意这个i+j,不是i ans=min(ans,sum); } cout<<ans<<endl; } return 0; }
3. 1787. Turn for MEGA
题意:有一个叫做"MEGA"的路口,给出这个路口每分钟可以通过车的数量k,和过去的时间n。接着再给出从1~n分钟每分钟到达该路口的车的数量a[i](这里a[1]表示在第1分钟内到达的车辆为a[1]个)。问最后一分钟该路口还剩多少车?
思路:刚看到这个题的时候,我是这样做的:k*n-(a[1]+a[2]+a[3]...a[n])。这里有个坑,比如k是5,n是3,然后a[]={0,0,6},5*3>6 很明显剩0辆, 但是实际情况是这样的:第1,2分钟时没有车,到第3分钟来了6辆,所以只能通过5辆,剩1辆。 按实际情况模拟即可AC
代码:
#include <iostream> using namespace std; int dp[101]={0}; //记录每分钟剩余的车辆 int main() { int n,k; cin>>n>>k; for(int i=0;i<k;i++) { if(i>0) dp[i]+=dp[i-1]; //加上前一分钟剩余的 int temp; cin>>temp; dp[i]+=temp-n; if(dp[i]<0) dp[i]=0; //剩余的车辆只能>=0 } cout<<dp[k-1]<<endl; return 0; }
4. 1788. On the Benefits of Umbrellas
题意:下雨天,公交车站,有n个女孩和m个男孩,每个男孩手里都有一把伞,而女孩手里没有。并且每个女孩都有一个怒气值i,男孩有一个怒气系数j。他们都要回学校,那么问题来了:如果没有男孩给某个女孩打伞,这个女孩会获得对应的怒气值,如果没有女孩和某个男孩作伴回去,那么这个男孩也会获得一个怒气值anger(anger=已经有女孩作伴的男孩的数量*自身的怒气系数)。问最后男女怎么匹配使得怒气总和最小,并输出这个值。
自己的思路:先按照怒气值从大到小排序,如果n>m,计算后面几个没有匹配的女孩的怒气和,输出即可。
如果n<m,暴力 从匹配1对~n对,依次算出怒气和,然后更新出最小值,输出即可。
代码:
#include <iostream> #include <algorithm> using namespace std; const int M=101; bool compare(int a,int b) { return a>b; } int a[M],b[M]; int main() { int n,m; cin>>n>>m; for(int i=0;i<n;i++) cin>>a[i]; for(int j=0;j<m;j++) cin>>b[j]; sort(a,a+n,compare); sort(b,b+m,compare); int mini=1000000000; if(m>n) { for(int t=0;t<=n;t++) //t是匹配对数 { int ans=0; for(int i=t;i<m;i++) { ans+=b[i]*t; } for(int i=t;i<n;i++) //计算怒气和 ans+=a[i]; if(mini>=ans) mini=ans; //更新最小值 } cout<<mini<<endl; } else { int ans3=0; for(int k=m;k<n;k++) ans3+=a[k]; cout<<ans3<<endl; } return 0; }
5. 1789. Searching for the Dodecahedron
题意:有n个盒子,从1~n编号。其中一个盒子里藏着宝藏(treasure),你每次只能翻开一个盒子,但是宝藏会在你翻开后向左或者向右移动一个位置。问按照什么顺序翻盒子一定能找出宝藏,并输出这个顺序。
思路:假设宝藏在奇数号盒子里,从1~n依次找一遍肯定能找到。没有找到说明宝藏在偶数号盒子里,恰好跳过。这样的话,分两种情况。
第一种情况:n为奇数,按最坏的情况(宝藏在偶数号盒子里),先从1~n翻一遍,由于n为奇数,宝藏就会跑到奇数号盒子里,再从1~n翻一遍即可。
第二种情况:n为偶数,也按最坏的情况(宝藏在偶数号盒子里),我们可以先翻开1号盒子,使宝藏跑到奇数号盒子里,然后在从1~n扫荡一遍即可。
代码:
#include <iostream> #include <cstdio> #include <cstring> #include <vector> using namespace std; int n; vector<int> v; int main() { while(cin>>n) { v.clear(); for(int i=1; i<=n; i++) v.push_back(i); if(n%2==0) v.push_back(1); //n为偶数,先放个1 for(int i=1; i<=n; i++) //再接着放1~n v.push_back(i); int len=v.size(); cout<<len<<endl; for(int i=0; i<len; i++) { if(i) cout<<" "; cout<<v[i]; } puts(""); } return 0; }
6. 1792. Hamming Code
题意:有四个圆(编号I,II, III, IV),位置摆放如下图,相交部分编号(1,2,3),这7部分每块的值只能为0或1。这四个圆相交的部分(比如3号)的值肯定是包含该部分的圆的值的和mod2。(比如Value[3]=(Value[I]+Value[II]+Value[IV])%2,Value[2]=(Value[I]+Value[III]+Value[IV])%2,and so on)。那么问题来了:给你这7部分的值,但有一位是错误的,要求你找出哪位是错的,把正确的输出。
思路:暴力即可,依次把每位的值换一下(0变1,1变0),再计算是否正确。如果不行再还原该值,继续尝试下一位。
代码:
#include <iostream> #include <cstdio> using namespace std; int a[10]= {0}; bool ok(int a1,int a2,int a3,int a4,int a5,int a6,int a7) { if((a1+a2+a4)%2!=a7) return false; if((a2+a3+a4)%2!=a5) return false; if((a1+a3+a4)%2!=a6) return false; return true; } int main() { for(int i=0; i<7; i++) cin>>a[i]; int flag=0; if(ok(a[0],a[1],a[2],a[3],a[4],a[5],a[6])) { flag=1; for(int i=0; i<7; i++) { printf("%d%c",a[i],i==6?' ':' '); } } if(flag==0) for(int i=0;i<7;i++) { a[i]^=1; if(ok(a[0],a[1],a[2],a[3],a[4],a[5],a[6])) { for(int i=0; i<7; i++) { printf("%d%c",a[i],i==6?' ':' '); } break; } a[i]^=1; } return 0; }
7. 1793. Tray 2
题意:给你一个盘子和两只碗,盘子长宽高分别是a,b,d。第一只碗的下圆面半径r1,上圆半径r2,第二只碗下圆半径p1,上圆半径p2。两只碗高度都为h。问是否能将这两只碗放到这个盘子里,要求碗底都必须挨着盘子。可以的话输出YES,否则输出NO。
思路:高中数学,计算即可。这样放(俯视图)
代码:
#include <iostream> #include <cstdio> #include <algorithm> using namespace std; double r1,r2,w1; double p1,p2,w2; double a,b,d,h; struct point //计算俩圆点距离的时候需要用坐标系 { double x; double y; } A,B; double dis(struct point A,struct point B) { return (A.x-B.x)*(A.x-B.x)+(A.y-B.y)*(A.y-B.y); } void yes() { puts("YES"); } void no() { puts("NO"); } int main() { while(cin>>a>>b>>d>>r1>>r2>>p1>>p2>>h) { if(a<b) swap(a,b); w1=r2; w2=p2; if(h>d) { w1=r1+d*(r2-r1)/h; w2=p1+d*(p2-p1)/h; } if(w1<w2) swap(w1,w2); if(w1*2>b) //先判断碗的直径是否大于盘子宽度 { no(); continue; } A.x=w1; A.y=w1; B.x=a-w2; B.y=b-w2; if(dis(A,B)>=(r2+p2)*(r2+p2)) { yes(); } else no(); } return 0; }
8. 1796. Amusement Park
题意:老师让孩子去买票,有面值为10, 50, 100, 500, 1000, 和 5000 的卢比(RMB和rouble都一样啦..),再告诉你每张票的价格price,老师只给孩子钱了,但没说要买几张。你需要计算出老师可能要买几张。
输入:这几种面额卢比的数量 和 票的价格。
输出:先几种情况,再输出每种情况分别买几张
思路:先看有没有和票价一样的卢比,如果有那肯定只有一种情况,就是用全部的钱去买票。如果面额最小的比票价还大,那么把面额最小的减去一张,计算最小值,再计算最大值,输出即可。
代码:
#include <iostream> using namespace std; int num[6]; int value[6]={10,50,100,500,1000,5000}; int main() { int sum=0; for(int i=0;i<6;i++) { cin>>num[i]; sum+=num[i]*value[i]; } int price; cin>>price; int mi; for(int i=0;i<6;i++) { if(num[i]>0) { mi=i; break; } } if(value[mi]!=price) { int pre=sum-value[mi]; int minnum=pre/price+1; int maxnum=sum/price; cout<<maxnum-minnum+1<<endl; for(int i=minnum;i<=maxnum;i++) cout<<i<<" "; cout<<endl; } else { cout<<1<<endl; cout<<sum/price<<endl; } return 0; }