Problem A: Press the switch
Time Limit: 1 Sec Memory Limit: 128 MB
Submit: 310 Solved: 78
[Submit][Status][Web Board]
Description
达达的家里有一串长度为n的灯泡,编号1,2,3,4…..n-1,n。每一个灯泡都有一个开关,达达每次选一个数a,把编号为a的倍数的灯泡的开关都按一遍。
假定灯刚开始都开着,他做了m次这样的事,问他爸妈打他没有?偶,不不不,问最后有几个灯开着。
Input
多组测试数据,第一行输入一个n(1<=n<=1e12)
第二行数输入一个数m(0<=m<=2)
接下来输入m个数ai(1<=ai<=min(1000,n))
Output
输出最后结果
Sample Input
100
1
2
5
2
2 3
100000000000
1
1
Sample Output
50
2
0
[分析]
这题交了无数次才a,真的是一路坎坷。
n超级大,一看见这个当时心里就有点凉了,感觉自己不会做。但是看见m只有0到2,瞬间就明白了,这就是一个数学问题。
当m=0,直接输出n,因为没有灯被关。
当m=1,输出n-n/a1,n/a1就是所有a1的倍数的个数。所有关掉a1的倍数灯为n-n/a1;
麻烦就在m=2;
因为减去a1倍数和a2倍数后会出现某几个灯被重复关。
那么这些重复的灯有多少呢,一开始我以为是n/(a1*a2);
所以m=2的式子是n-n/a1-n/a2+n/(a1*a2);
交上去wa了。几番修改,提交,测试,发现一组数据100 20 5输入时答案不对。
发现重复的灯个数应该是lcm(a1,a2)(a1和a2的最小公倍数)。
所以m=2的式子是n-n/a1-n/a2+n/lcm(a1*a2);
依旧wa,内心是绝望的。又是几番测试发现,其实很简单,因为是重复关闭,所以要+2n/lcm(a1,a2);
于是ac了。
[代码]
#include
long long gcd(long long a, long long b)//最大公约数
{
return b ? gcd(b, a%b) : a;
}
long long lcm(long long a, long long b)//最小公倍数
{
return a / gcd(a, b)*b;
}
int main()
{
long long n,m,a1,a2;
while(scanf("%lld",&n)!=EOF)
{
scanf("%lld", &m);
if (m == 0)printf("%lld\n", n);
else if (m == 1)
{
scanf("%lld", &a1);
printf("%lld\n", n - (n / a1));
}
else if (m == 2)
{
scanf("%lld%lld", &a1, &a2);
printf("%lld\n", n - (n / a1) - (n / a2) + 2*(n / lcm(a1,a2)));
}
}
}
Time Limit: 1 Sec Memory Limit: 128 MB
Submit: 163 Solved: 97
[Submit][Status][Web Board]
Description
给出n(n<=10000)个正整数,每个数xi<=15000.可以在这个n个数中选择一些数出来,至少选择一个,是否存在一种选择方案使得选择出
来的数的和是n的整数倍
Input
第一行一个T(T<=500),第二行一个数n,接下来n个正整数
Output
Case #x: y,其中x是测试编号,从1开始,y表示答案,如果存在y为Yes,否则为No
Sample Input
2
5
1 2 3 4 1
2
1 2
Sample Output
Case #1: Yes
Case #2: Yes
[分析]
很邪门,就是感觉不可能不是,居然A了。。。。玄学。。
之后研究
[代码]
#include
int main()
{
int t,x;
scanf("%d", &t);
int kase = 0;
while (t--)
{
int n;
scanf("%d", &n);
for (int i = 0; i"%d", &x);
}
printf("Case #%d: Yes\n", ++kase);
}
return 0;
}
Time Limit: 1 Sec Memory Limit: 128 MB
Submit: 297 Solved: 85
[Submit][Status][Web Board]
Description
生活在杭州,大家是不是习惯了出门只带一只手机就好啦,无论是大商场还是街边小摊都能用上支付宝,不得不说真是方便呀,知识改变命运,科技改变生活,代码改变世界,每当放假回家,我就回到了没有支付宝的地方了,然后,就要使用人民币啦,麻烦的是大部分情况下是要找零,为了不找零,于是我决定事先做好准备,我把钱数好,然后放在一个个钱袋里面,以便在我现有的支付能力下,任何数目的钱,我都能够使用我事先准备好的小钱进行支付。当然,我很穷所以我想用最少的钱袋来实现这个愿望,并且不存在两个钱袋中装有相同的大于1的钱数。假设我有m个1元硬币,你能猜到我会用多少个钱袋?
Input
第一行T(T<=1000000),接下来一个整数,表示我现有的总的硬币数目m,其中,1≤m ≤1000000000
Output
Case #x: y,x表示测试编号从1开始,y一个整数表示答案
Sample Input
2
3
4
Sample Output
Case #1: 2
Case #2: 3
[分析]
没找到规律的时候开大数组各种循环很难受wa了,然后测试的时候循环输出了1到100,发现其实袋数相同的个数是前一个的两倍,如何就很开心了(case真是个好东西)
[代码]
#include
using namespace std;
int main()
{
int t, m,kase=0;
scanf("%d", &t);
while(t--)
{
int ans = 0;
scanf("%d", &m);
while (m)
{
m = m / 2;
ans++;
}
printf("Case #%d: %d\n", ++kase, ans);
}
return 0;
}
Time Limit: 1 Sec Memory Limit: 128 MB
Submit: 216 Solved: 84
[Submit][Status][Web Board]
Description
给出N个数,要求把其中的重复的去掉,只保留第一次出现的数.1 <= N <= 50000,给出的数在32位有符号整数范围内。
Input
第一行T(T<=10),接下来一个数n,接下来n个数
Output
Case #x: y1,y2,…,x是测试编号从1开始,y_i表示答案
Sample Input
2
11
1 2 18 3 3 19 2 3 6 5 4
6
1 2 3 4 5 6
Sample Output
Case #1: 1 2 18 3 19 6 5 4
Case #2: 1 2 3 4 5 6
[分析]
水题,用map,代码看一下一般就懂了(其实用set就可以了,我一直没学)
[代码]
#include
#include
using namespace std;
int main()
{
int t;
int kase = 0;
map<int, int>mp;
scanf("%d", &t);
while(t--)
{
mp.clear();
int n,x;
scanf("%d", &n);
printf("Case #%d:", ++kase);
while(n--)
{
scanf("%d", &x);
if (mp[x] == 0)
{
mp[x] = 1;
printf(" ");
printf("%d", x);
}
}
printf("\n");
}
}
Problem G: 艰难的起床
Time Limit: 1 Sec Memory Limit: 128 MB
Submit: 215 Solved: 122
[Submit][Status][Web Board]
Description
冬天最令人讨厌的事情就是起床吧!达达每天都要早起去上班,所以他就会定一个闹钟,闹钟一响他就会起床。
但是由于被子的封印结界太强,直接起床是不可能的。达达和被子长期战斗,有了丰富的经验,被子的封印每隔10分钟就会削弱1。
现在告诉你达达的闹钟时间T1,和起床时间T2,能否求得被子的最大可能封印能力。
Input
多组测试数据。
输入T1,T2。多组测试数据。
保证T2时刻在T1之后,并且是同一天的时间。
Output
输出结果。
Sample Input
7:00 7:10
7:00 7:11
7:33 8:30
Sample Output
1
1
5
[分析]
水。
[代码]
#include
int main()
{
int h1, m1,h2,m2;
while (scanf("%d:%d %d:%d", &h1, &m1, &h2, &m2) != EOF)
{
int time1 = h1 * 60 + m1;
int time2 = h2 * 60 + m2;
int time = time2 - time1;
printf("%d\n", time / 10);
}
}