目录
A-HDU 2097
题述
Sky从小喜欢奇特的东西,而且天生对数字特别敏感,一次偶然的机会,他发现了一个有趣的四位数2992,这个数,它的十进制数表示,其四位数字之和为2+9+9+2=22,它的十六进制数BB0,其四位数字之和也为22,同时它的十二进制数表示1894,其四位数字之和也为22,啊哈,真是巧啊。Sky非常喜欢这种四位数,由于他的发现,所以这里我们命名其为Sky数。但是要判断这样的数还是有点麻烦啊,那么现在请你帮忙来判断任何一个十进制的四位数,是不是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.
B-HDU 2098
题述
把一个偶数拆成两个不同素数的和,有几种拆法呢?
输入
输入包含一些正的偶数,其值不会超过10000,个数不会超过500,若遇0,则结束。
输出
对应每个偶数,输出其拆成不同素数的个数,每个结果占一行。
样例
输入
30
26
0
输出
3
2
C-HDU 6702
题述
现在我们有两个正整数A和B,请找出一个正整数C,使得式子( (A xor C)&(B xor C) )最小 (xor是异或运算)
当然,如果使得式子最小的C为0时,请你输出1
输入
第一行输入T,代表有T组数据
接下来每一行输入两个数A,B(A,B<=2^32)
输出
对于每一组数据输出一个正整数C
样例
输入
1
3 5
输出
1
D-计蒜客 30990
题述
我们描述 K:
k! = 1 * 2 * …* (k - 1) *k
我们表示 S:
S = 1 * 1! + 2 * 2! + … +
(n - 1) * (n-1)!
然后 S 对 n 去模是 ___________
你将得到一个整数n.
你需要计算 S 对 n 取模的值
输入
第一行输入一个整数 T(T < 1000), 表示测试用例的行数.
对于每个测试用例,都有一行包含一个整数 n.
输出
对于每个测试用例,打印一个整数 S 对 n 取模后的值.
提示
第一个测试用例 S = 1* 1!= 1, 并且 1 的模 2 运算 1.
第二个测试用例 S = 11!+2 2!= 5 , 并且 5 对 3 取模是 2.
样例
输入
2
2
3
输出
1
2
E-HDU 2040
题述
古希腊数学家毕达哥拉斯在自然数研究中发现,220的所有真约数(即不是自身的约数)之和为:
1+2+4+5+10+11+20+22+44+55+110=284。
而284的所有真约数为1、2、4、71、 142,加起来恰好为220。人们对这样的数感到很惊奇,并称之为亲和数。一般地讲,如果两个数中任何一个数都是另一个数的真约数之和,则这两个数就是亲和数。
你的任务就编写一个程序,判断给定的两个数是否是亲和数
输入
输入数据第一行包含一个数M,接下有M行,每行一个实例,包含两个整数A,B; 其中 0 <= A,B <= 600000 ;
输出
对于每个测试实例,如果A和B是亲和数的话输出YES,否则输出NO。
样例
输入
2
220 284
100 200
输出
YES
NO
F-HDU 1846
题述
十年前读大学的时候,中国每年都要从国外引进一些电影大片,其中有一部电影就叫《勇敢者的游戏》(英文名称:Zathura),一直到现在,我依然对于电影中的部分电脑特技印象深刻。
今天,大家选择上机考试,就是一种勇敢(brave)的选择;这个短学期,我们讲的是博弈(game)专题;所以,大家现在玩的也是“勇敢者的游戏”,这也是我命名这个题目的原因。
当然,除了“勇敢”,我还希望看到“诚信”,无论考试成绩如何,希望看到的都是一个真实的结果,我也相信大家一定能做到的~
各位勇敢者要玩的第一个游戏是什么呢?很简单,它是这样定义的:
1、 本游戏是一个二人游戏;
2、 有一堆石子一共有n个;
3、 两人轮流进行;
4、 每走一步可以取走1…m个石子;
5、 最先取光石子的一方为胜;
如果游戏的双方使用的都是最优策略,请输出哪个人能赢。
输入
输入数据首先包含一个正整数C(C<=100),表示有C组测试数据。
每组测试数据占一行,包含两个整数n和m(1<=n,m<=1000),n和m的含义见题目描述。
输出
如果先走的人能赢,请输出“first”,否则请输出“second”,每个实例的输出占一行。
样例
输入
2
23 2
4 3
输出
first
second
G-HDU 2084
题述
在讲述DP算法的时候,一个经典的例子就是数塔问题,它是这样描述的:
有如下所示的数塔,要求从顶层走到底层,若每一步只能走到相邻的结点,则经过的结点的数字之和最大是多少?
已经告诉你了,这是个DP的题目,你能AC吗?
输入
输入数据首先包括一个整数C,表示测试实例的个数,每个测试实例的第一行是一个整数N(1 <= N <= 100),表示数塔的高度,接下来用N行数字表示数塔,其中第i行有个i个整数,且所有的整数均在区间[0,99]内。
输出
对于每个测试实例,输出可能得到的最大和,每个实例的输出占一行。
样例
输入
1
5
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5
输出
30
H-CodeForces 1430A
题述
熊熊是一名csgo玩家,在沙二驰骋多年的他,显然已经对这个地方了如指掌。他恐怖的定位和风骚的身法以及高超的战术让他的队友后悔来到这个地方。尤其是他的大狙,当他扛着笨重的awp走到中门时,每一声枪响都会有人应声倒地。但是熊熊有个奇怪的癖好,他每一次只杀奇数个数的人,一杀他嫌太少,九杀又太多,所以他每一局他只会打出三杀,五杀或七杀。现在你在他旁边看他打游戏,你看到他杀了n个人,你现在想知道他分别打出了多少个三杀,五杀或七杀。
输入
第一行的整数 t(1<=t<=1000)— 测试用例的个数.
每个测试用例只有一个输入数据 — lrh杀人的总数 n(1<=n<=1000)
输出
如果对于某个测试样例,没有正确的答案,则输出 -1.
否则,输出3个正整数-三杀的个数,五杀的个数,七杀的个数 — 如果存在多个情况,输出任意一种即可
样例
输入
4
30
67
4
14
输出
2 2 2
7 5 3
-1
0 0 2
I-CodeForces 1430B
题述
你有 n个 桶放在一排 , 从左到右开始编号分别为1~n. 最初, 第 i 桶装的水是 ai 升.
你可以把水从一个桶倒到另一个桶。 在这个过程中, 你可以两个选择两个桶 x 和y (第 x个桶不应该为空) 然后从桶x 向桶 y 倒水(可能是所有的水).你可以假设桶的容量是无限的,所以你可以在每个桶里倒入任何数量的水。
如果最多可以倒水 k 次.计算桶中最大和最小水量之间的最大可能差。
举例
- 如果你有四个桶,每个桶里装5升水,k=1,你可以从第二个桶里倒5升水到第四个桶里,所以桶里的水量是[5,0,5,10],最大和最小的差值是10;
- 如果所有的桶都是空的,你就不能做任何操作,所以最大和最小的量之差仍然是0。
输入
第一行包含一个整数 t (1 < t < 1000) — 测试用例的数量
每个测试用例的第一行包含两个整数 n 和 k(1 <= k < n < 2<= 10^5) — 桶数和可以浇注的数量。
第二行包含 n 整数 a1, a2, … an (0 <=ai <=10^9), 其中ai 是第 i 个桶的初始水量。
保证 n 个以上测试用例的总和不超过 2 * 10^5.
输出
F对于每个测试用例,如果最多可以倒水k 次,请打印桶中最大和最小水量之间的最大可能差值。
样例
输入
2
4 1
5 5 5 5
3 2
0 0 0
输出
10
0
J-CodeForces 1430C
题述
「融合」是《游戏王》集换式卡牌游戏中的一张通常魔法卡,是最早对融合怪兽进行融合召唤的魔法卡,也是进行融合召唤的泛用魔法卡。
现在zwt也想练习一下融合,他的目标转向了数组
每次zwt可以选择两个不同的数字,并且大喊一声“フュージョン!!!”,然后这两个数字就会融合,变成他们和的一半(向上取整)放到数组里
现在有一个序列1,2,3,4,………,n,zwt想知道他要施法几次,每一步选择哪几个数字,这个数组才能变成一个数,并且使得这个最后留下的数字最小
如n=4,
1.选择a=2,b=3,数组变为[1,3,3]
2.选择a=3,b=3,数组变为[1,3]
3.选择a=1,b=3,数组变为[2]
如果有多种方案,输出任意一种
输入
第一行输入位t[1,1000],表示有t组数据
每组数据的第一行为n[2,200000]
n的总和不会超过200000
输出
对于每组数据输出最后留下的最小的那个数字
之后n-1行依次输出步骤
样例
输入
1
4
输出
2
2 4
3 3
3 1
题解
A
思想:主要考虑进制转换问题,十进制转是二进制,十进制转十六进制。与二进制大同小异,不断做除法并取余。代码如下:
#include <stdio.h>
int main(void)
{
int a[3],b[3];
int i,sum,m,n;
a[0]=10;
a[1]=12;
a[2]=16;
while(scanf("%d",&n)!=EOF)
{
if(n==0)
break;
for(i=0;i<3;i++)
{
m=n,sum=0;
while(m!=0)
{
sum+=m%a[i];
m/=a[i];
}
b[i]=sum;
}
if(b[1]==b[0]&&b[1]==b[2])
printf("%d is a Sky Number.\n",n);
else
printf("%d is not a Sky Number.\n",n);
}
return 0;
}
B
思想:利用素数筛法,有不懂的可以去这个博客素数筛法(素筛)学习一下,总结的很到位了。
#include <stdio.h>
#include <math.h>
void sieveofe(int p[], int n)
{
int i, j;
p[0] = 0;
p[1] = 0;
p[2] = 1;
for(i=3; i<=n; i++)
{
p[i++] = 1;
p[i] = 0;
}
int max = sqrt(n);
for(i=3; i<=max; i++){
if(p[i]) {
for(j=i+i; j < n; j+=i
p[j]=0;
}
}
}
#define MAX 10000
int main(void)
{
int p[MAX+1];
int sum, count, i;
sieveofe(p, MAX);
for(;;) {
scanf("%d", &sum);
if(sum == 0)
break;
count = 0;
for(i=2; i<=sum / 2; i++) {
if(p[i] && p[sum-i])
if(i != sum-i)
count++;
}
printf("%d\n", count);
}
return 0;
}
代码出处HDU2098 分拆素数和【筛选法】
C
思想:
看上图真值表。
#include <stdio.h>
int main(void)
{
long long int a,b,c,t;
scanf("%lld", &t);
while(t--)
{
scanf("%lld%lld", &a, &b);
if((a&b)==0)
printf("1\n");
else
printf("%lld\n", a&b);
}
return 0;
}
D
思想:看样例!!看样例!!找规律!!
Tips:数值减一。
E
思想:暴力法,依次求他们的约束,看是否相等。
#include <stdio.h>
int main(void)
{
int M;
while(scanf("%d",&M)!=EOF)
{
for(int i=0;i<M;i++)
{
int A,B,j,k,sum=0,num=0;
scanf("%d%d",&A,&B);
for(j=1;j<A;j++)
{
if((A%j)==0)
sum+=j;
else
continue;
}
for(k=1;k<B;k++)
{
if((B%k)==0)
num+=k;
else
continue;
}
if(num==A&&sum==B)
printf("YES\n");
else
printf("NO\n");
}
}
return 0;
}
F
思想:经典巴什博弈:
最多取m个,如果剩下m+1个是不是无论第一个人如何取,后手都能一次取完也就是说:无论他们前边如何拿如果n=(m+1)r+s(换句话说就是当先手拿走s个时,后手总能保证剩下的为m+1的整数倍,则后手必胜,否则先手必胜)
例如:先手拿走s个,后手拿走k个保证剩下的是(m+1)的整数倍,则后手必胜,如果先手拿走s个使得剩下的为(m+1)的整数倍,则先手必胜
结论:n % (m+1) == 0,后手必胜;否则先手必胜。
#include<stdio.h>
int main(void)
{
int c,n,m;
scanf("%d",&c);
while(c--)
{
scanf("%d%d",&n,&m);
if(n%(m+1)==0)
printf("second\n");
else
printf("first\n");
}
return 0;
}
G
思想:DP算法,局部优化。从最下层,两两取最大。
#include<stdio.h>
int max(int a,int b)
{
int t;
if(a>b)
{ t=a;
a=b;
b=t;
return t;
}
else
return b;
}
int main(void)
{
int a[101][101];
int c;
scanf("%d",&c);
while(c--)
{
int n;
int i,j;
scanf("%d",&n);
for(i=0;i<n;i++)
{
for(j=0;j<=i;j++)
scanf("%d",&a[i][j]);
}
for(i=n-2;i>=0;i--)
{
for(j=0;j<=i;j++)
{
a[i][j]+=max(a[i+1][j],a[i+1][j+1]);
}
}
printf("%d\n",a[0][0]);
}
return 0;
}
H
思想:暴力求解
# include<stdio.h>
int main()
{
int n=0,m=0,i=0,j=0,k=0;
scanf("%d",&m);
while(m--)
{ scanf("%d",&n);
int flag=0;
for( i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
for( k=0;k<n;k++)
{
if(3*i+5*j+7*k==n)
{
flag=1;
break;
}
}
if(flag==1)
break;
} if(flag==1)
break;
}
if(flag==0)
printf("%d\n",-1);
else
printf("%d %d %d\n",i,j,k);
}
return 0;
}
I
思想:给水的多少排序,每次把第二多的加到最多的里面。最后得出最多的。
#include<stdio.h>
#include<algorithm>
using namespace std;
int main(void)
{
int t,i;
scanf("%d",&t);
for(i=0;i<t;i++)
{
int n,k,j,l,a[1100],t,sum=0;
scanf("%d%d",&n,&k);
for(j=1;j<=n;j++)
{
scanf("%d",&a[j]);
}
sort(a+1,a+n+1);
while(k!=0)
{
a[n]+=a[n-k];
k--;
}
printf("%d\n",a[n]);
}
return 0;
}
J
思想:明确你不论如何操作最小值都会是2,其实每次去哪两个都可以,但是官方题解是每次取最大的两个,可能他想贪心一下
#include<stdio.h>
int main(void)
{
int t;
scanf("%d",&t);
while(t--)
{
int n;
scanf("%d",&n);
printf("2\n");
printf("%d %d\n",n-1,n);
for(int i=n-2;i>=1;--i)
printf("%d %d\n",i,i+2);
}
return 0;
}