比赛心得
这次比赛可以说打的很自闭,360°无死角展示了一名蒟蒻的垂死挣扎。通过这次难得的比赛,我也充分认识到学习算法如果不通过大量做题巩固,在比赛时会非常陌生,影响发挥。鉴于这是第一次参加这种组队自闭,我还是要认真总结每一道题。
problem A - - Euphoria 与梦中学习
HDU 2136 Largest prime factor 最大的素因数
HDU 2136 Largest prime factor(5000/1000ms Java/others)
题面:
Euphoria听着那高深莫测的数学公式就这样去了梦乡,复杂多变又严谨具有逻辑性的东西确实可以击垮Euphoria。
在梦里,一切又都变得那么虚无缥缈。
Euphoria回到了他初中的时代,又是熟悉的教师、熟悉的同桌以及熟悉的…
“好了同学们,我们今天讲什么是质数”
梦境中的老师有力地敲了敲黑板说道:“质数(prime number)又称素数,有无限个。质数定义为在大于1的自然数中,除了1和它本身以外不再有其他因数。”
恐怕Euphoria要做梦中梦了…
快乐的时光总是过的飞快,在现实生活中已经响起了下课铃,梦中的Euphoria在脱离梦境的前一刻,梦中的课堂也下课了。
“好了各位同学们,我们现在布置作业”,梦境中的老师说:“每个人都知道任何数字都可以由若干个素数的和来表示。现在,你们的作业是告诉我某个正整数的最大的素因数的位置。素数2的位置是1,素数3是2,素数5是3等。特别的,数字1的位置是0…”
Euphoria仿佛遇到了梦魇一样,都睡着了还要写作业。请你编写一个程序帮帮Euphoria,找出某一个正数的最大素因数的位置。
输入:
第一行输入一个数N(1 <= N <= 300)。在接下来的N行中,每行输入一个正整数M(1 <= M <= 1000000)。
输出:
对于每个M,输出一行结果,表示M的最大素因数的位置。
输入用例:
5
1
2
3
4
5
输出用例:
0
1
2
1
3
个人比赛时的想法:
题目让输出最大素因数的位置,我当时想的是我把素数打表,
然后对输入的数求出其最大素因数,然后在表中查找,输出其在表中的下标。
嗯,蒟蒻的想法后来被大佬的思路按在地上摩擦。
你总是把题复杂化,哎。
我当时的代码(这个代码超时了,记不清了,比赛时改过了,大概思路就是这样子)
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
int prime[1000005]; //打表
int check[1000005];
int tot;
int place;
void isprime(int n) //这是线性筛
{
check[0]=0;
for(int i=2;i<=n;i++){
if(check[i]==0)prime[++tot]=i;
for(int j=1;(j<=tot)&&(i*prime[j]<=n);j++){
check[i*prime[j]]=1;
if(i%prime[j]==0)break;
}
}
}
bool binsearch(int array_a[],int length,int key) //这是一个二分查找
{
int left=0,right=tot,mid;
while(left<=right){
mid=(left+right)/2;
if(key<array_a[mid])right=mid-1;
else if(key>array_a[mid])left=mid+1;
else{
place=mid;
return true;
}
}
return false;
}
int main()
{
int N,M,x;
cin>>N;
isprime(1000000); //靠靠靠靠,又忘了这一行,当时比赛时一直没写这行
while(N--){
cin>>M; //先判断第一个素因数,
if(M==1)cout<<"0"<<endl;
int i=1;
while(i<=sqrt(M)){
if(M%i==0){
x=M/i;
if(binsearch(prime,tot,x)){
cout<<place<<endl;
break;
}
i++; //靠靠靠靠靠,忘记打这一行
}
}
}
return 0;
}
贴一下参考的代码(orz)
#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <set>
#include <string.h>
#include <stdio.h>
#include <conio.h>
#include <math.h>
using namespace std;
int map[1000005] = {0};
int main(void) {
int count = 1;
for (int i = 2; i < 1000005; ++i) {
if (map[i] == 0) {
for (int j = 1; j * i < 1000005; ++j) {
map[i * j] = count;
}
count++;
}
}
int n;
while (~scanf("%d", &n)) {
printf("%d\n", map[n]);
}
return 0;
}
伤心,自闭
probem B - -Eurphoria 与人类进步的阶梯
买书(计蒜客)(1000ms)
题面
“Hey,Euphoria!我来给你讲个故事吧!”
“蛤???”
“传说,有两副眼镜,一副…”
“我懂!我买就是了!”
上面是昨天Euphoria和G-fat的一次对话,是的,地球上最著名的理财软件又告诉Euphoria理财的时间到了!
这可让Euphoria再也无心学习,坐在教室的最后一排拿起手机,看着那琳琅满目的学习资料(跑),在经过仔细的考虑过后,Euphoria决定购买以下几款学习资料:
(1). 传火之路有你有我——古代西方历史学
(2). xxxx的阴谋之影子die两次——古代东亚历史学
(3). 一分钟跳伞模拟器——战争学
(4). 编号第六的彩虹——未来军事学
Euphoria是一个不折不扣的强迫症,他必须要把手头的所有钱花到一分不剩才罢休,随着购物车重量越来越重,这个问题也变得逐渐复杂了起来。
Euphoria又看了看手中的钱,发现自己并不能买完购物车内的所有东西,只好挑几个不错的游戏,并且可以把手头的钱都花完。
请你写一个程序,来判断Euphoria能否刚好把手头的钱花完?
输入:
第一行输入三个整数,Euphoria手头中仅仅只有可怜的N元钱,但是他在购物车中添加了M件商品,在经过不断地思索之后,悲惨的Euphoria决定从中买K件商品来以此度过五月。
第二行输入M个正整数,第i个数代表着第i个学习资料的费用。
看着那即将入手的学习资料,Euphoria心中更是激动了…
其中M(1 <= M <= 100000000), N(1 <= N <= 30), K(1 <= K <= min(N,8))
输出:
如果Euphoria刚好能满足自己的强迫症,用所有手头的钱买下来自己想要买的K件学习资料,那么输出一行
Happy Euphoria
反之则输出一行
Happy Bu Neng
输入样例#1
15 6 4
20 2 9 4 3 1
输出样例#1
Happy Euphoria
解释:因为手头的15元 = 2 + 9 + 3 + 1这四件商品,所以Euphoria可以快乐。
输入样例#2
10 5 2
1 2 3 4 5
输出样例#2
Happy Bu Neng
解释:因为不存在任何2个学习资料加起来可供Euphoria刚好将手头的前花完,所以Euphoria快乐不能
好累啊,这是一个经典的深度优先搜索(DFS)模板题,只要抄模板就好,但是比赛时题目的数据有问题,大家都没过,我本来以为这道题过了,结果竟然错了,哇,心态爆炸,感觉没错,后来学长改了数据就过了。
代码:
#include<iostream>
using namespace std;
int n,m,k;
int a[35];
bool dfs(int i,int sum)
{
if(i==k)return sum==n; //结束条件
else{
if(dfs(i+1,sum))return true;
if(dfs(i+1,sum+a[i]))return true;
}
return false;
}
void solve()
{
if(dfs(0,0))cout<<"Happy Euphoria"<<endl;
else cout<<"Huppy Bu Neng"<<endl;
}
int main()
{
cin>>n>>m>>k;
for(int i=0;i<m;i++)
cin>>a[i];
solve();
return 0;
}
Problem C --Euphoria 与梦中情人
这是最自闭的,总感觉可以过但老错,后来学长说这是一道找规律题,我靠。(⊙﹏⊙)
我的代码就不放了,放下参考代码吧。
ECNU 3651 仰望星空(512MB,2000ms)
题面:
Euphoira和他未来的另一半Ariohpue就这样安安静静地坐在草地上。
Euphoria就这样用眼角瞅着Ariohpue,但Ariohpue什么话都不说。
Euphoria知道,语言是造成误会的根源。
但是,Euphoria也知道,每天,Ariohpue会坐得离Euphoria更近一些。
Euphoria和Ariohpue一起抬头仰望着满是星星的天空,Euphoria心中的星星对Ariohpue而言也只不过是像沙漠中的一颗微小沙粒。
Ariohpue喜欢抬头看着天空中的银河,银河中的星星都有可能是Ariohpue的朋友,但Euphoria深信他自身不会是万众中的一颗不起眼的星星。
在Euphoria下定决心后,Euphoria准备默默地记录他和Ariohpue每天仰望星空时,两个人之间的距离。
Euphoria惊喜地发现,他和Ariohpue两人之间的距离,或许不变,或许在减少,但一定不会增加。
可是,时间总是残酷的,会从Euphoria的记忆里抹去很多重要的事情。或许是Euphoria和Ariohpue一起这样的时间太长了,长到了Euphoria只记得他们第一天在星空下的距离。
今天,两人之间的距离是A;Euphoria和Ariohpue又在一起,就那样安安静静地坐在草地上仰望星空。Euphoria却突然想知道,在这N天来,他和Ariohpue之间的距离之和。
由于可怜的Euphoria已经不记得每天的具体距离,他的脑海中除了Ariohpue的身影(和传火)别无他物。他只能依稀记得,他和Ariohpue第一天的距离是B,这样看似不能解决距离之和的问题了,所以Euphoria只想知道在这幸福的N天中的距离之和有多少种不同的可能性。
输入:
第一行输入一个整数T,代表有T组测试用例(1 <= T <= 2000)
每组测试用例包含一行,包含三个整数 N, A, B (2 ≤ N ≤ 10^9, 1 ≤ A ≤ B ≤ 10^9),分别表示他们一起仰望星空的天数、今天他们之间的距离以及第一天他们之间的距离。
输出:
对于每组输入样例,输出一行一个整数,表示不同可能和的个数。
输入样例:
2
3 1 2
4 1 3
输出样例:
2
5
Hint:
对于第一组测试用例,在3天内,两个人之间的距离的答案有{2, 2, 1}与{2, 1, 1},所以有两组不同的和,故答案为2。
代码:
#include <iostream>
using namespace std;
int main() {
//ios::sync_with_stdio(false);
//cin.tie(nullptr);
long long N, A, B;
int T;
cin >> T;
while (T--) {
cin >> N >> A >> B;
cout << ((N - 1) * B + A) - ((N - 1) * A + B) + 1 << endl;
}
return 0;
}
不说了,竟然是一道找规律题,我还是太嫩了。
Problem D --Eurphoria 与逮虾户
不说了,签到题,判断大小就行
题面:
Euphoria经常在上课的时候睡觉,这是一个很不好的习惯!
今天Euphoria在上课的时候又睡着了,在梦乡中他见到了他的两个好朋友老Q和老Z,令Euphoria惊讶的是,老Q和老Z这两个花花公子正在坐在那里喝茶嗑瓜子!
Euphoria很好奇地凑了过去,发现曾经爱互相竞争的他们现在吃个瓜子都在比赛!这让Euphoria很是不解,难道比谁的嘴先因为嗑瓜子而磨破吗?
Euphoria坐在他们旁边,飘渺的云彩,强壮的松树和崎岖的岩石并没有吸引Euphoria的眼球,相反的是Euphoria一直盯着老Q和老Z二人,想看看他们到底在玩什么。
老Q和老Z似乎在玩一个复杂到难以理解的游戏。第一个人有N堆瓜子,另一个人有M堆瓜子。然后第一个人先手从任意一堆瓜子中吃掉任意整数个瓜子,然后第二个人再吃…谁先把瓜子吃完谁就赢了。
他们发现了Euphoria的到来,并盛情邀请Euphoria来和他们solo这场比赛,为了公平起见,他们总让Euphoria先手吃瓜子。如果Euphoria输了则需要继续玩下去直到永远。
Euphoria才不想一直在这里呆下去,他还要回宿舍去传火,现在Euphoria想知道他是否可以确保先手必胜!请你写一个程序帮帮Euphoria,让他可以早日回去传火!
输入:
第一行包含整数T(1 ≤ T ≤ 100)代表测试用例数。然后是T个测试用例。
每个测试用例的输入格式如下:
第一行包含两个整数N,M(1 ≤ N, M ≤100),分别是Euphoria和他的对手面前瓜子的堆书。
下面一行包含N个整数ai(1 ≤ ai ≤ 1000),其中每个整数表示Euphoria面前第i堆瓜子的瓜子数。
最后一行包含M个整数bi(1 ≤ bi ≤ 1000),其中每个整数表示他的对手面前的第i堆瓜子中的瓜子数。
输出:
如果Euphoria先手必胜,则输出一行YES,否则输出NO
输入样例:
3
5 2
1 2 3 4 5
1 1
2 2
1 1
8 8
2 5
1 1
1 2 3 4 5
输出样例:
NO
YES
YES