HDU:2097,2098,1021,2035 解题报告
2012-12-06 17:14
411 查看
HDU这四道题相对来讲都是很简单的,其中主要用到了初等数论的一些基础知识。
2097:Sky数
http://acm.hdu.edu.cn/showproblem.php?pid=2097
题目简要:
通过判断一个四位数十进制、十二进制及十六进制下的各数字之和是否相等来判断它是不是Sky数。
输入:
输入含有一些四位正整数,如果为0,则输入结束。
输出:
若n为Sky数,则输出“#n is a Sky Number.”,否则输出“#n is not a Sky Number.”。每个结果占一行。注意:#n表示所读入的n值。
范例输入:
2992
1234
0
范例输出:
2992 is a Sky Number.
1234 is not a Sky Number.
解析:
仔细阅读题目后可以得到一个很清晰的思路,即写一个函数用于转换进制,然后再对转换后的三个数字进行比较即可。
代码:
2098:分拆素数和
http://acm.hdu.edu.cn/showproblem.php?pid=2098
题目简要:
把一个偶数拆成两个不同素数的和,有几种拆法呢?
输入:
输入包含一些正的偶数,其值不会超过10000,个数不会超过500,若遇0,则结束。
输出:
对应每个偶数,输出其拆成不同素数的个数,每个结果占一行。
范例输入:
30
26
0
范例输出:
3
2
解析:
我们可以先除去素数的倍数,因为素数的倍数肯定不是素数。然后只需对0~偶数的前一半枚举,因为加和可拆成i + (n - i) (i代表当前枚举到的数,n代表偶数)。
1021:Fibonacci Again
题目简要:
给出F(0) = 7, F(1) = 11, F(n) = F(n-2) + F(n-1) , 算出F(n)是否能被3整除。
输入:
输入一系列的行,每行包括一个整数n。(n<1,000,000)
输出:
如果满足被3整除的条件则打印"yes“,否则打印"no"。
范例输入:
0
1
2
3
4
5
范例输出:
no
no
yes
no
no
no
解析:
斐波那契数列有一个通项公式,可以算出在F(0) = 0, F(1) = 1的情况下的F(n),甚至也可以推广到前两项任意的情况,即当F(0) = a, F(1) = b时有F(n) = F(n-2)*a + F(n-1)*b,不过本题如果直接套用这个公式,将会面临溢出的问题(因为n最大可能会接近1000000),所以想必套公式是行不通的。不过也许你在测试上述公式的时候突然发现似乎输出呈现出了固定的规律,F(2) = F(6) = F(10) = ... = F(2+4*(k-1)),所以这时我们只需判断当n-2是否能被4整除即可。
2035:人见人爱A^B
http://acm.hdu.edu.cn/showproblem.php?pid=2035
题目简要:
求A^B的最后三位数表示的整数。
输入:
输入数据包含多个测试实例,每个实例占一行,由两个正整数A和B组成(1<=A,B<=10000),如果A=0, B=0,则表示输入数据的结束,不做处理。
输出:
对于每个测试实例,请输出A^B的最后三位表示的整数,每个输出占一行。
范例输入:
2 3
12 6
6789 10000
0 0
范例输出:
8
984
1
解析:
对于这种次方数很大的题目,肯定不会考虑直接连乘(因为很容易就溢出了),所以要用到数论里的一个基础知识:(a * b) % p = (a % p * b % p) % p。而题目中只需要得到最后三位数,则只需mod 1000即可。
2097:Sky数
http://acm.hdu.edu.cn/showproblem.php?pid=2097
题目简要:
通过判断一个四位数十进制、十二进制及十六进制下的各数字之和是否相等来判断它是不是Sky数。
输入:
输入含有一些四位正整数,如果为0,则输入结束。
输出:
若n为Sky数,则输出“#n is a Sky Number.”,否则输出“#n is not a Sky Number.”。每个结果占一行。注意:#n表示所读入的n值。
范例输入:
2992
1234
0
范例输出:
2992 is a Sky Number.
1234 is not a Sky Number.
解析:
仔细阅读题目后可以得到一个很清晰的思路,即写一个函数用于转换进制,然后再对转换后的三个数字进行比较即可。
代码:
#include <iostream> using namespace std; string trans(int n, int b) { char a[16] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'}; string r = ""; while (n != 0) { r = a[n%b] + r;n /= b; } return r; } int add(string n) { int r = 0,i; for (i=0;i<n.size();i++) { if (n[i] >= 65 && n[i] <= 70) r += n[i] - 55; else r += n[i] - 48; } return r; } int main() { int n; while (cin >> n && n != 0) { string c1 = trans(n,10); string c2 = trans(n,12); string c3 = trans(n,16); if (add(c1) == add(c2) && add(c2) == add(c3)) cout << n << " is a Sky Number." << endl; else cout << n << " is not a Sky Number." << endl; } return 0; }
2098:分拆素数和
http://acm.hdu.edu.cn/showproblem.php?pid=2098
题目简要:
把一个偶数拆成两个不同素数的和,有几种拆法呢?
输入:
输入包含一些正的偶数,其值不会超过10000,个数不会超过500,若遇0,则结束。
输出:
对应每个偶数,输出其拆成不同素数的个数,每个结果占一行。
范例输入:
30
26
0
范例输出:
3
2
解析:
我们可以先除去素数的倍数,因为素数的倍数肯定不是素数。然后只需对0~偶数的前一半枚举,因为加和可拆成i + (n - i) (i代表当前枚举到的数,n代表偶数)。
#include <cstdio> bool p[10001]; int main() { for(int i = 2;i <= 100; i ++) if(!p[i]) for(int j = i + i;j <= 10000;j += i) p[j] = 1; int n; while(scanf("%d",&n), n) { int c = 0; for(int i = 2;i <= n / 2 ;i ++) if(i < n - i && !p[i] && !p[n - i]) c++; printf("%d\n",c); } return 0; }
1021:Fibonacci Again
题目简要:
给出F(0) = 7, F(1) = 11, F(n) = F(n-2) + F(n-1) , 算出F(n)是否能被3整除。
输入:
输入一系列的行,每行包括一个整数n。(n<1,000,000)
输出:
如果满足被3整除的条件则打印"yes“,否则打印"no"。
范例输入:
0
1
2
3
4
5
范例输出:
no
no
yes
no
no
no
解析:
斐波那契数列有一个通项公式,可以算出在F(0) = 0, F(1) = 1的情况下的F(n),甚至也可以推广到前两项任意的情况,即当F(0) = a, F(1) = b时有F(n) = F(n-2)*a + F(n-1)*b,不过本题如果直接套用这个公式,将会面临溢出的问题(因为n最大可能会接近1000000),所以想必套公式是行不通的。不过也许你在测试上述公式的时候突然发现似乎输出呈现出了固定的规律,F(2) = F(6) = F(10) = ... = F(2+4*(k-1)),所以这时我们只需判断当n-2是否能被4整除即可。
#include<stdio.h> int main() { int n; while(scanf("%d",&n)!=EOF { if((n-2)%4!=0) printf("no\n"); else printf("yes\n"); } return 0; }
2035:人见人爱A^B
http://acm.hdu.edu.cn/showproblem.php?pid=2035
题目简要:
求A^B的最后三位数表示的整数。
输入:
输入数据包含多个测试实例,每个实例占一行,由两个正整数A和B组成(1<=A,B<=10000),如果A=0, B=0,则表示输入数据的结束,不做处理。
输出:
对于每个测试实例,请输出A^B的最后三位表示的整数,每个输出占一行。
范例输入:
2 3
12 6
6789 10000
0 0
范例输出:
8
984
1
解析:
对于这种次方数很大的题目,肯定不会考虑直接连乘(因为很容易就溢出了),所以要用到数论里的一个基础知识:(a * b) % p = (a % p * b % p) % p。而题目中只需要得到最后三位数,则只需mod 1000即可。
#include <iostream> using namespace std; int main() { int a,b; while (cin >> a >> b && (a != 0 && b != 0)) { int s = 1; while (b > 0) { s*=a; if (s >= 1000) s%=1000; b--; } cout << s << endl; } return 0; }
相关文章推荐
- 杭电acm1021 hdu-acm-1021解题报告
- HDU解题报告——1021
- HDU解题报告——1789
- 【解题报告】HDU 4616 Game - 树形dp
- HDU 2196解题报告
- HDU 5862 Counting Intersections 解题报告
- HDU - 1166 敌兵布阵 解题报告(树状数组魔板题)
- hdu 1068 解题报告
- HDU:1465不容易系列之一解题报告
- HDU 4632 Palindrome subsequence 解题报告
- Hdu 1232 畅通工程 解题报告
- HDU 4642 Fliping game 解题报告
- HDU - 3450 Counting Sequences解题报告(动态规划+离散化+树状数组+二分查找)
- hdu 1142 A Walk Through the Forest 最短路+记忆化搜索 解题报告
- hdu 1527取石子游戏(威佐夫博奕)(解题报告)
- HDU1863 畅通工程 解题报告--prim
- HDU 1010 Tempter of the Bone 解题报告
- hdu 4001解题报告
- Hdu 2099之解题报告
- 杭电acm1019 hdu-acm-101解题报告