本文共 3651 字,大约阅读时间需要 12 分钟。
【...】
网上代码比较多我就尽量不挂了,简单讲下思路吧。
oj :
【Problem A: 画正方形】
签到题,注意下输出格式(组与组之间有且仅有一个空行)就行。
至于怎么注意..判断第一组输出前不输出空行或者最后一组输出后不输出空行就行...反正几组数据都告诉你了。
如果几组数据未知就判断第一组然后改变状态即可。
【Problem B: 勇者斗恶龙】
简单贪心。把恶龙每个头的直径和骑士的能力存到数组里然后升序(或者降序也行)排序,然后按恶龙(或者骑士也行)的头的直径从小到大去匹配能力从小到大的骑士,保证最优解,如果头最大的那个可以匹配到对应的骑士,那么就输出解,否则无解。这里我用了sort()函数,因为方便,自行百度头文件和用法,还可以结构体排序哦。
//其中一种做法#include//这其实是万能头文件了,自行百度using namespace std; main() { int n,m,i,j,a[20005],b[20005]; while(~scanf("%d%d",&n,&m),n&&m) { for(i=0;i =a[i]) { sum+=b[j]; i++; } j++; } if(i==n) printf("%d\n",sum); else printf("Loowater is doomed!\n"); } }
【Problem C: 求余】
这里要注意数据范围n∈[1,10^2000],所以肯定不能直接存然后拿来取余,我们要定义一个字符数组来存。这里提一点不要每次开数组大小都刚好卡数据,容易出问题的。然后我们一个个把数字取出来,边取边取余即可。如下:
#includeint main() { char a[2010]; int k,i,n; while(~scanf("%s%d",&a,&k)){ int n=0; for(i=0;a[i]!='\0';i++) n=((10*n)%k+a[i]-'0')%k; printf("%d\n",n); } return 0; }
【Problem D: 小学问题(听说100人99个第一次答错)】
水题,输出a+d即可。
【Problem E: 互质】
这里,辗转相除法(欧几里得算法)求最大公因数了解一下。然后循环判断计数即可。
int gcd(int a, int b){ return b==0?a:gcd(b,a%b);}
【Problem F: 求 1 + 1/2! +...+ 1/n!】
水题。
【Problem G: 判断素数】
水题。不过有兴趣的同学可以去了解下素数筛。
传送门:
【Problem H: 龟兔赛跑预测】
好像也没什么好讲的..算出总时长即乌龟抵达终点的时长,然后一秒秒判断龟兔赛跑的状态,我加点注释好了~
#includeint main() { int v1,v2,t,s,l,sum1=0,sum2=0; scanf("%d%d%d%d%d",&v1,&v2,&t,&s,&l); int t1=0,t2=l/v2; while(t1<=t2) { t1++; if(t1>t2) break; //乌龟都到终点了 sum1+=v1; sum2+=v2; if(sum1>=l) break; //兔子优先抵达终点 if(sum1-sum2>=t) //兔子要休息啦 { t1+=s; sum2+=s*v2; } } if(sum1
【Problem I: 凶手】
如果能直接推就输出答案,不能的话就来写自定义函数吧~代码如下:
#include#include int f[7];int A(){ if (!f[0]) return 1; return 0;}int B(){ if (f[0]||f[2]) return 1; return 0;}int C(){ if (!A()&&!B()) return 1; return 0;}int F(){ if (f[5]) return 1; return 0;}int D(){ if (!C()&&!F()) return 1; return 0;}int E(){ if (A()&&D()&&!B()&&!C()&&!F()) return 1; return 0;}int main(){ for(int i=0;i<6;i++) { memset(f,0,sizeof(f)); f[i]=1; if(A()+B()+C()+D()+E()+F()==3) //因为一半说了假话就判断为真的数目是否等于3 printf ("%c\n",'A'+i); } return 0;}
【Problem J: zbj的长跑】
自己画一下图就会发现当n*m%2==0的时候可以刚好跑遍每个打卡点回到寝室,否则最优情况是最后跑两个点之间的斜线。
#include#include int main(){ int n,m; while(~scanf("%d%d",&n,&m)) { if(n*m%2==0) printf("%.2lf\n",1.0*n*m); else printf("%.2lf\n",n*m-1+sqrt(2)); }}
【Problem K: Parity check】
规律题。虽然是英文题但是也很容易懂,就是输出f(n) mod 2 的结果。敲黑板,注意一下数据范围。定义一个字符数组存一下,然后推一下规律,0,1,1,0,1,1...易得循环节长度为3,然后我们把数字取出来,边转换边取模(因为是3所以可以直接取出来求和判断,如果两位数以上就要边转换边取模了),然后判断一下输出答案即可。
//核心代码int k=0;for(int i=0;i
【Problem L: 一生之敌】
思维题。
因为b^2=2*a*(a+1)^2<=1e19,所以a<=3e6。
b*b=2*a*(a+1)*(a+1) --> b=sqrt(2*a)*(a+1) 。 枚举i=sqrt(2*a),a=i*i/2 ,则b=i*(a+1)。
数据比较大需要用unsigned long long。
vector可以看做是未定义长度的数组,vector的用法可以了解一下。
传送门:
STL中的二分函数:
1.binary_search:查找某个元素是否出现。
2.lower_bound:查找第一个大于或等于某个元素的位置。
3.upper_bound:查找第一个大于某个元素的位置。
自行了解~当然手写二分也行的我就不贴代码了~
#includeusing namespace std; typedef unsigned long long ull; vector vec; main() { ull i,a=0,n; for(ull i=0;a*(i+1)<=1e19;i+=2) { a=i*i/2; vec.push_back(i*(a+1)); } int t; scanf("%d",&t); while(t--) { scanf("%llu",&n); int ans=lower_bound(vec.begin(),vec.end(),n)-vec.begin(); printf("%llu\n",vec[ans]); } }
【对不起没忍住】
哎呀我超开心的!!!
转载地址:http://tyben.baihongyu.com/