模拟赛部分题解(校赛)

比赛心得

这次比赛可以说打的很自闭,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

problem L

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值