1、Knights in Chessboard LightOJ - 1010
题意:在n*m的棋盘上最多能放马多少个?
思路:设n最小。如果n为1,则可以放m个;如果n=2,可以放满一个田,空一个田,再放,最后剩下的为min(4,m%4*2);其他,则最多可以放棋盘的一半。
1 #include<iostream> 2 #include<algorithm> 3 #include<cstdio> 4 using namespace std; 5 int main() 6 { 7 int t; 8 scanf("%d", &t); 9 int Case = 1; 10 while (t--) 11 { 12 int n, m; 13 scanf("%d%d", &n, &m); 14 if (m < n) n = n ^ m, m = n ^ m, n = n ^ m; 15 if (n == 1) printf("Case %d: %d ", Case++, m); 16 else if (n == 2) printf("Case %d: %d ", Case++, m / 4 * 4 + min(4, m % 4 * 2)); 17 else printf("Case %d: %d ", Case++,(n*m+1)/2); 18 } 19 20 21 return 0; 22 }
2、A Childhood Game LightOJ - 1020
题意:两个人轮流拿石头,每次只能拿1个或2个。如果Bob先手,拿到最后一块石头的人获胜;如果Alice先手,拿到最后一块石头的人失败。给出若干询问,求获胜者。
思路:找到必败态和必胜态。
1 #include<iostream> 2 #include<cstdio> 3 using namespace std; 4 int main() 5 { 6 int t,Case=1; 7 scanf("%d", &t); 8 while (t--) 9 { 10 int num; 11 char name[10]; 12 scanf("%d%s", &num, name); 13 if (name[0] == 'B') 14 { 15 if (num%3==0) printf("Case %d: Alice ", Case++); 16 else printf("Case %d: Bob ", Case++); 17 } 18 else 19 { 20 if ((num-1)%3==0) printf("Case %d: Bob ", Case++); 21 else printf("Case %d: Alice ",Case++); 22 } 23 } 24 return 0; 25 }
3、Integer Divisibility LightOJ - 1078
题意:求n的倍数中只含有k这个数字的数的最小位数。
思路:同余定理。对每次数位+1,只需要原数对n取膜的结果,因为即使带上整除n的部分不断*10最后仍能整除n,反而可能由于数过大而错误。
1 #include<iostream> 2 #include<cstdio> 3 using namespace std; 4 int main() 5 { 6 int t; 7 int Case = 1; 8 scanf("%d", &t); 9 while (t--) 10 { 11 int n, k; 12 scanf("%d%d", &n, &k); 13 int ans = k % n; 14 int bits = 1; 15 while (ans%n) 16 { 17 ans = (ans * 10 + k%n) % n; 18 bits++; 19 } 20 printf("Case %d: %d ",Case++, bits); 21 } 22 return 0; 23 }
4、Ekka Dokka LightOJ - 1116
题意:如果w可以由一个奇数和偶数乘积得到,输出奇数最小时的方案。
思路:判断w的奇偶性。偶数时不断除2。
1 #include<iostream> 2 #include<cstdio> 3 using namespace std; 4 int main() 5 { 6 int t; 7 scanf("%d", &t); 8 int Case = 1; 9 while (t--) 10 { 11 unsigned long long w; 12 scanf("%lld", &w); 13 if (w % 2 == 1) printf("Case %d: Impossible ", Case++); 14 else 15 { 16 long long init = w; 17 while (w % 2 == 0) w /= 2; 18 printf("Case %d: %lld %lld ", Case++, w,init/w); 19 } 20 } 21 return 0; 22 }
5、Mad Counting LightOJ - 1148
题意:询问n个人,每个说出除他自己外镇里支持自己喜欢的球队的人数。求小镇的最小人数。
思路:对于总支持人数都为a的有k个人,如果k整除a,说明至少有k/a只球队,否则有k/a+1只球队,每只球队支持人数都为a个人。
1 #include<iostream> 2 #include<cstdio> 3 #include<map> 4 #include<set> 5 using namespace std; 6 int main() 7 { 8 int t; 9 scanf("%d", &t); 10 int Case = 1; 11 while (t--) 12 { 13 int n; 14 scanf("%d", &n); 15 set<int>s; 16 map<int, int>mp; 17 for (int i = 1; i <= n; i++) 18 { 19 int num; 20 scanf("%d", &num); 21 s.insert(num); 22 if (!mp.count(num)) mp[num] = 0; 23 mp[num]++; 24 } 25 int ans=0; 26 set<int>::iterator it = s.begin(); 27 for (; it != s.end(); it++) 28 { 29 ans += (mp[(*it)] / (*it + 1))*(*it + 1)+((mp[*it] % (*it + 1) == 0) ? 0 : (*it + 1)); 30 } 31 printf("Case %d: %d ", Case++, ans); 32 } 33 return 0; 34 }
6、Josephus Problem LightOJ - 1179
题意:有t个询问,每次有n个人,数到k的人死去,求最后存活的人的编号。
思路:约瑟夫环问题。假设编号从0开始,数到dis的那个人死去。已知总共i-1人时第survive(i-1)个人最后活着,那么总共i个人时,如果第一次死去1个人,那么将他之后的人重新编号.最后活的人是新编号后的survive(i-1).这个survive(i-1)人的编号在总共i个人时的映射编号为survive(i)=(survive(i-1)+dis)%i.
1 #include<iostream> 2 #include<cstdio> 3 using namespace std; 4 int main() 5 { 6 int t; 7 scanf("%d", &t); 8 int Case = 1; 9 while (t--) 10 { 11 int n, dis; 12 scanf("%d%d", &n, &dis); 13 int survive = 0;//1个人时,最后活的是他自己,假设编号从0开始 14 for (int i = 2; i <= n; i++) 15 { 16 //假设编号从0开始,数到dis的那个人死去。已知总共i-1人时第survive个人最后活着,那么总共i个人时,如果第一次死去1个人,那么将他之后的人重新编号最后活的人时survive.这个survive人的编号在总共i个人时的映射编号为(survive+dis)%i. 17 survive = (survive + dis) % i; 18 } 19 printf("Case %d: %d ", Case++, survive+1); 20 } 21 return 0; 22 }
7、Large Division LightOJ - 1214
题意:求一个大数(-10200 ≤ a ≤ 10200)是否能被int型整数b除。
思路:大数除法
string:
1 #include<iostream> 2 #include<string> 3 #include<cmath> 4 #include<cstdio> 5 using namespace std; 6 void D_M(string &a, int b, string &d, string &m) 7 {//求一个大数除以一个int范围内的整数的商和余数 8 long long beichu = 0; 9 int c = a.length(); 10 int sthead = 0; 11 if (a[0] == '-') sthead = 1;//略去负号 12 string tmp; 13 for (int i = sthead; i < c; i++) 14 { 15 beichu = beichu * 10 + a[i] - '0'; 16 tmp.push_back(beichu / b + '0'); 17 beichu = beichu % b; 18 } 19 while (beichu) 20 { 21 m.push_back(beichu % 10 + '0'); 22 beichu /= 10; 23 } 24 if (m == "") m.push_back('0'); 25 int led = m.length() - 1, st = 0; 26 while (st < led) 27 { 28 char tc = m[st]; 29 m[st] = m[led]; 30 m[led] = tc; 31 st++; 32 led--; 33 } 34 int cur = 0, sz = tmp.length(); 35 while (cur < sz&&tmp[cur] == '0') cur++; 36 if (cur == sz) d = "0"; 37 else d = &tmp[cur]; 38 } 39 40 int main() 41 { 42 int t; 43 scanf("%d", &t); 44 int Case = 1; 45 while (t--) 46 { 47 string a, d="",c=""; 48 int b; 49 cin >> a; 50 scanf("%d", &b); 51 D_M(a, abs(b), c, d); 52 if (d == "0") printf("Case %d: divisible ", Case++); 53 else printf("Case %d: not divisible ", Case++); 54 } 55 return 0; 56 }
char *:
1 #include<iostream> 2 #include<string> 3 #include<cmath> 4 #include<cstdio> 5 using namespace std; 6 void Div_of_BigNum(char *chu, int beichu, char *shang, char *yushu) 7 { 8 int st = 0; 9 int pt_shang = 0, pt_yushu = 0; 10 if (chu[0] == '-') st = 1; 11 bool isfu = false; 12 if ((st&&beichu > 0) || (st == 0 && beichu < 0)) 13 { 14 shang[pt_shang++] = '-'; 15 isfu = true; 16 } 17 if (beichu < 0) beichu = -beichu; 18 long long tmp = 0; 19 for (int i = st; chu[i] != '