数学题一

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\n", Case++, m);
16         else if (n == 2) printf("Case %d: %d\n", Case++, m / 4 * 4 + min(4, m % 4 * 2));
17         else printf("Case %d: %d\n", Case++,(n*m+1)/2);
18     }
19 
20 
21     return 0;
22 }
View Code

 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\n", Case++);
16             else printf("Case %d: Bob\n", Case++);
17         }
18         else
19         {
20             if ((num-1)%3==0) printf("Case %d: Bob\n", Case++);
21             else printf("Case %d: Alice\n",Case++);
22         }
23     }
24     return 0;
25 }
View Code

 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\n",Case++, bits);
21     }
22     return 0;
23 }
View Code

 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\n", Case++);
14         else
15         {
16             long long init = w;
17             while (w % 2 == 0) w /= 2;
18             printf("Case %d: %lld %lld\n", Case++, w,init/w);
19         }
20     }
21     return 0;
22 }
View Code

 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\n", Case++, ans);
32     }
33     return 0;
34 }
View Code

 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\n", Case++, survive+1);
20     }
21     return 0;
22 }
View Code

 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\n", Case++);
53         else printf("Case %d: not divisible\n", Case++);
54     }
55     return 0;
56 }
View Code

 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] != '\0'; i++)
20     {
21         tmp = tmp * 10 + chu[i] - '0';
22         if (tmp >= beichu) shang[pt_shang++] = '0' + tmp / beichu;
23         tmp = tmp % beichu;
24     }
25     if (tmp)
26     {
27         int t_len = 0, ttmp = tmp;
28         while (ttmp) ttmp /= 10, t_len++;
29         for (int i = t_len - 1; i >= 0; i--) yushu[i] = '0' + tmp % 10, tmp /= 10;
30         pt_yushu = t_len;
31     }
32     else yushu[pt_yushu++] = '0';
33     shang[pt_shang] = yushu[pt_yushu] = '\0';
34 }
35 char s[210], dst[210], yu[210];
36 int main()
37 {
38     int t;
39     scanf("%d", &t);
40     int Case = 1;
41     while (t--)
42     {
43         int b;
44         scanf("%s%d",s, &b);
45         Div_of_BigNum(s,b,dst,yu);
46         if (yu[0] =='0') printf("Case %d: divisible\n", Case++);
47         else printf("Case %d: not divisible\n", Case++);
48     }
49     return 0;
50 }
View Code

 只判断能否被整除:

 1 #include<iostream>
 2 #include<string>
 3 #include<cmath>
 4 #include<cstdio>
 5 using namespace std;
 6 bool Div_of_BigNum(char *chu, int beichu)
 7 {
 8     int st = 0;
 9     int pt_shang = 0, pt_yushu = 0;
10     if (chu[0] == '-') st = 1;
11     if (beichu < 0) beichu = -beichu;
12     long long tmp = 0;
13     for (int i = st; chu[i] != '\0'; i++)
14     {
15         tmp = tmp * 10 + chu[i] - '0';
16         tmp = tmp % beichu;
17     }
18     if (tmp) return false;
19     else return true;
20 }
21 char s[210];
22 int main()
23 {
24     int t;
25     scanf("%d", &t);
26     int Case = 1;
27     while (t--)
28     {
29         int b;
30         scanf("%s%d",s, &b);
31         if (Div_of_BigNum(s, b)) printf("Case %d: divisible\n", Case++);
32         else printf("Case %d: not divisible\n", Case++);
33     }
34     return 0;
35 }
View Code

 

posted @ 2018-03-16 14:04  萌萌的美男子  阅读(224)  评论(0编辑  收藏  举报