HBCPC2018 部分题解

Mex Query

icebound的商店

Nim Game

神殿

跑图

520

icebound的账单

Beautiful Array

Mex Query

题目描述:
Give nnn non-negative integers, please find the least non-negative integer that doesn’t occur in the nnn numbers.
输入:
The first line is an integer TTT, representing the number of test cases.

For each test case:
The first line of each test case is an integer nnn
The second line of each test case are nnn non-negative integers aia_iai​
T<=10
n<=2∗1052*10^52∗105
0<=aia_iai​<=2312^{31}231
输出:
for each test case, output a line with the answer.

题解:水题一枚 题目大意就是让找出序列中第一个缺失的整数,例如1 2 3,缺失的就是0,例如0 1 2 3 4 缺失的就是5。
此题的坑点在如果序列中存在重复的元素需要去掉。
解题思路就是用一个set来存储序列,去重+排序,之后遍历到第一个缺失的值输出即可

AC代码:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 2e5;
const int INF = 0x3f3f3f3f;
int main(void)
{int T, n, t;scanf("%d", & T);while(T--) {set<int> st;     scanf("%d", &n);for(int i = 0; i < n; ++i) {scanf("%d", &t);st.insert(t);       //插入,排序并去重}int res = 0;bool flag = false;for(auto it = st.begin(); it != st.end(); ++it) {if(*it != res) { //遍历到中间有缺失值的位置printf("%d\n", res);flag = true;break;}res++;}if(!flag) printf("%d\n", res);// 如果是0 1 2 3 这样的的情况输出最后一位数+1就是 4}return 0;
}

icebound的商店

题目描述:
icebound在得到神殿的宝藏之后,开了一家神秘的商店。你来到了商店,发现慷慨的icebound搞了TTT次促销活动。在每次促销活动中,icebound都会想出一个他喜欢的数字,如果你买的商品的总价刚好等于icebound喜欢的数字,那么你就可以免费得到这些商品。
icebound的商店里一共有 15 件商品,商品的价格和这家商店一样神秘,第一件商品的价格是 1 元,第二件商品的价格是 2元,设第n件商品的价格为wnw_nwn​ 元,则:
wn=wn−1+wn−2(3≤n≤15)w_n=w_{n-1}+w _{n−2}(3≤n≤15)wn​=wn−1​+wn−2​(3≤n≤15)
如果在某次活动中icebound喜欢的数字是 4,那么共有 4 种购买方案:

1. 买 4个 第一种商品
2. 买 2个 第一种商品 和 1个 第二种商品
3. 买 2个 第二种商品
4. 买 1个 第一种商品 和 1个 第三种商品

请你算出共有多少种方案可以免费购物,方案数对1000000009取模。
输入:
第一行给出一个整数TTT,表示icebound搞了TTT次活动。

接下来的TTT行每行给出一个正整数xxx,表示在这次活动中icebound喜欢的数字。

1≤T≤1 \leq T \leq1≤T≤ 3000

1≤x≤30001 \leq x \leq 30001≤x≤3000

输出:
输出TTT行,每行输出一个正整数。

第i行的正整数表示在第i次活动中免费购物的方案数,方案数对1000000009取模。

题解:
首先判断价值的序列公式为斐波那契数列,由于只有15项,先打一个表存下前15个数
之后的思路类似于一维的01背包
dp[j]表示买价格为i的物品的方案数
状态转移方程为:
dp[j]=(dp[j]+dp[j-fib[i]])%MOD

AC代码

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 2e6;
const int MOD = 1e9 + 9;
int fib[50];
int dp[3005];
inline void init() //打出前15项商品的价格
{fib[1] = 1, fib[2] = 2;for(int i  = 3; i <= 15; ++i) fib[i] = fib[i - 1] + fib[i - 2];
}
int main()
{init();int T, x;scanf("%d", &T);while(T--) {scanf("%d", &x);memset(dp, 0, sizeof dp);dp[0] = 1;for(int i = 1; i <= 15; ++i) //遍历15个商品for(int j = fib[i]; j <= x; ++j){dp[j] = (dp[j] + dp[j - fib[i]]) % MOD;//商品选和不选的情况求和}printf("%d\n", dp[x] % MOD);}return 0;
}

Nim Game

题目描述:
Nim is a mathematical game of strategy in which two players take turns removing objects from distinct heaps. On each turn, a player must remove at least one object, and may remove any number of objects provided they all come from the same heap
The goal of the game is to avoid being the player who doesn’t have any object to remove. The player who remove the last project is the winner.
Now KK and TT are playing Nim game with the optimal strategy. There are n heaps of stones.
The number of stones in i−thi -thi−th heap is aia_iai​
​They play this game mm times, and KK is the player making the first move. During the i−thi-thi−th time they play the game on the heaps whose index in interval [lil_ili​,rir_iri​] KK wants to know whether he has a winning strategy or not.
输入:

Input

The input consists of several test cases. The first line of the input gives the number of test cases, T(1≤T≤1031\le T\le 10^31≤T≤103)T

For test case, the first line contains two integers n(1≤n≤1061\le n\le 10^61≤n≤106)
) and m(1≤m≤1061\le m\le 10^61≤m≤106), representing the number of heap of stones and the game times.

The second line contains nn positive integers a1a_1a1​,a2a_2a2​,⋯\cdots⋯,ana_nan​(1≤ai≤1091\le a_i\le 10^91≤ai​≤109) representing The number of stones in i−thi-thi−th heap.

In the next mm lines, each line contains two integers li,ril_i,r_ili​,ri​ which means thei−thi-thi−th game is played on the interval [lil_ili​,rir_iri​]
It’s guaranteed that∑\sum∑ n≤2×106n\le 2\times 10^6n≤2×106
and ∑m≤2×106\sum m\le 2\times 10^6∑m≤2×106
输出:
For each test case, let fif_ifi​represents the answer of the i−thi-thi−thgame.If KK has a winning strategy in the i−thi-thi−th game then fif_ifi​=1,otherwisefif_ifi​=0.Please output ∑\sum∑fi∗2m−imod109+7f_i∗2^{ m−i} mod 10^9+7fi​∗2m−imod109+7,in which 1≤i≤m1\le i\le m1≤i≤m.

题解:
题目大意:这是个Nim游戏,每次输入n和m分别代表堆数和进行m轮游戏
这个和普通Nim游戏稍有不同的地方在于这个每一次会给出你对应的堆区间,比如我现在有5堆,每一堆个数分别为1 2 3 4 5,我选择1 3,就代表选择1 2 3这三堆为本轮的堆数
之后就是测试这区间的堆数的异或值是否为0,如果为0,KK必败,不为0 KK必胜
坑点:需要记录一个前缀异或和pre数组,不然会超时,每次给出[l,r],只需要pre[r]^pre[l-1]即可

AC代码

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 2e6;
const int MOD = 1e9 + 7;
int arr[N + 5];
ll pre[N + 5];
ll powmod(ll a, ll b)
{ll res=1;a %= MOD;while(b){if(b & 1) res = res * a % MOD;a=a * a % MOD;b >>= 1;}return res;
}
int main(void)
{int T, n, m, l, r;scanf("%d", &T);while(T--) {pre[0] = 0;scanf("%d %d", &n, &m);for(int i = 1; i <= n; ++i) {scanf("%d", arr + i);pre[i] = pre[i - 1] ^ arr[i]; //记录异或前缀和}ll sum  = 0;for(int i = 1; i <= m; ++i) {scanf("%d %d", &l, &r);if(pre[r] ^ pre[l - 1]) {//一个数如果异或两次等于没有异或过,比如1^2^3^2=1^3sum += powmod(2, m - i);sum %= MOD; //记得取模}}printf("%lld\n", sum % MOD);}return 0;
}

神殿

题目描述:
icebound通过勤工俭学,攒了一小笔钱,于是他决定出国旅游。这天,icebound走进了一个神秘的神殿。神殿由八位守护者守卫,总共由64个门组成,每一道门后都有一个迷宫,迷宫的大小均为100×100100 \times 100100×100。icebound在迷宫中总共耗时T小时,消耗食物K公斤。历经千辛万苦之后,icebound终于穿越了迷宫,到达了神殿的中心。神殿的中心有一个宝箱。宝箱上显示有两个正整数l和r。icebound苦思冥想,终于发现一些打开宝箱的线索。你需要找到一个数P,它具有一个美妙的性质:它是[l,r]中所有数的二进制表示里,1的个数最多的一个数。如果你发现了这个美妙的数字,你就可以打开宝箱,获得巨额财富。
比如[4,8]中

4: 0100
5: 0101
6: 0110
7: 0111
8: 1000

二进制表示中11的个数最多的数是7,它含有3个1。
输入:
输入一行,两个正整数:ll和rr,用空格隔开,代表神殿中宝箱上显示的数。

1≤T&lt;2311 \leq T &lt; 2^{31}1≤T<231

1≤K≤1051 \leq K \leq 10^51≤K≤105

1≤l≤r≤2×1091 \leq l \leq r \leq 2 \times 10^{9}1≤l≤r≤2×109

输出:
一个十进制数P,代表满足条件的解。如果有多个P满足条件,输出最小的P。

题解:
题目意思很明确,求区间内二进数中1最多的那个数是几。
思路现场赛可以暴力,但是之后数据加强了就需要一点技巧了。
这里用到了位或运算 " | "
位或运算比如2和3 二进制分别为 10 和11
1 0
1 1
———
1 1 ------>对于每一位来说有1为1,同0为0,所以结果为3
只用求L到R区间中的位或和,前提是不能超过R

AC代码

#include <bits/stdc++.h>
using namespace std;
int main()
{long long l, r;scanf("%lld %lld", &l, &r);while((l | (l + 1)) <= r) {l |= (l + 1);}printf("%lld\n", l);return 0;
}

跑图

题目描述:
跑图是RPG游戏中很烦躁的事情。玩家需要跑到距离他最近的传送点的位置。现在给你一张N×MN \times MN×M的方格图,每个方格中数值0表示为平地,数值1表示为传送点,你的任务是输出一张N×MN \times MN×M的矩阵,MatrixxyMatrix_{xy}Matrixxy​
​ 表示从(x,y)(x,y)到距离它最近的传送点的距离。 这里的距离是曼哈顿距离,(x1,y1)(x_1,y_1)(x1​,y1​) →\rightarrow→(x2,y2)(x_2,y_2)(x2​,y2​)的距离为∣x1−x2∣+∣y1−y2∣。|x_1-x_2|+|y_1-y_2|。∣x1​−x2​∣+∣y1​−y2​∣。

输入:
第一行,有两个数n,m接下来n行,每行m个数。

数据保证至少有一个传送点。

1≤n≤5001 \leq n \leq 5001≤n≤500,1≤m≤5001 \leq m \leq 5001≤m≤500

输出:
n行,每行m个数,表示某个点到离它最近的传送点的距离。

题解:
用广度优先搜索BFS。所谓的曼哈顿距离就是坐标差绝对值之和,可以理解为从每个为1的点到四个方向为0的点的最小值。
这里可以先把所有的起始点1放入队列,保证优先到达的点是最近的距离。距离用一个距离数组d来存储。

AC代码

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
typedef pair<int,int> P;
int d[505][505];
int arr[505][505];
int vis[505][505];
int m,n;
int dx[][2]={1,0,-1,0,0,1,0,-1};//四个方向
queue<P>q;
void bfs()
{while(!q.empty()){P tp=q.front();q.pop();vis[tp.first][tp.second]=1;for(int i=0;i<4;i++){int xx=tp.first+dx[i][0];int yy=tp.second+dx[i][1];if(xx>=0&&xx<n&&yy>=0&&yy<m&&!vis[xx][yy]&&arr[xx][yy]!=1)//点不越界不重复访问,不访问1即起始点{vis[xx][yy]=1;q.push(P(xx,yy));d[xx][yy]=d[tp.first][tp.second]+1;//更新访问点的距离}}}
}
int main()
{cin>>n>>m;for(int i=0;i<n;i++){for(int j=0;j<m;j++){scanf("%d",&arr[i][j]);if(arr[i][j]==1){q.push(P(i,j));}}}bfs();for(int i=0;i<n;i++)//打印距离数组即可{for(int j=0;j<m;j++){if(j < m - 1)cout<<d[i][j]<<" ";else cout << d[i][j];}cout<<endl;}return 0;
}

520

题目描述:
“又到了五月了呢”,icebound望着五月的天空,眼角流出了泪痕。那一年,icebound还是一个懵懂的少年。那一年,她还是一个青涩纯真的少女。在那一次偶然的相遇之中,他们之间擦出了爱情的火花。他们欢笑着,奔跑着,他们展望着美好的未来,向往着幸福的明天。她像 icebound 心海中的灯塔,像icebound 头顶上的星辰,即使在海里浮沉,即使在夜里摸爬,心中也不会感到迷茫,感到阴寒。他们努力,奋进,向着六月的那一站前行。可是,美好总是短暂的。那海上的灯塔不再发出温情的光亮,那天空中的星辰不再绽放出温柔的色彩。那一站,到达了,icebound 得到了终点,但icebound 永远失去了她,也失去了他的心。

”侯门一入深似海,从此萧郎是路人“

今天是2018年5月20日,又是一年的520。这一天,icebound不小心读到上面的诗,icebound沉思着,回想起与她曾经的快乐时光,icebound留下了n滴眼泪。icebound的每滴眼泪都带有太多的伤感之情了,以至于每滴眼泪都会感染到其他的生物,使得许多生物都一起掉下了眼泪。kk通过观察得知,当icebound流出n滴眼泪时,所有生物产生的眼泪总数为2n2^n2n
。现在,kk需要你帮助他写一个程序,计算当icebound流出n滴眼泪时,所有生物产生的眼泪总数PP,对 20180520 取模。

输入:
一个正整数n,代表icebound留下眼泪的个数。1≤n≤2×1091 \leq n \leq 2 \times 10^91≤n≤2×109

输出:
一个正整数P,代表所有生物产生的眼泪总数,对 20180520 取模。

题解:
题解:故事很是感人,但这他喵的就是个快速幂呀,我们看到n很大所以不能暴力,所以用快速幂

AC代码

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 2e5;
const int MOD = 20180520;
ll n;
ll Powmod()
{ll res=1;ll a=2;while(n){if(n&1) res = res * a % MOD;a=a*a%MOD;n>>=1;}return res;
}
int main(void)
{scanf("%lld",&n);printf("%lld\n",Powmod());return 0;
}

icebound的账单

题目描述:
icebound从小就有记账的习惯。又到了月末icebound统计资金状况的时候。icebound每个月除了不停的挥霍以外,有时他会良心发现,勤工俭学,因此会有一些微薄的收入。然而icebound数学不好,需要你来帮助他统计他本月的资金状况。

你将会得到一份icebound的账单,一共有 n​ 行整数,其中正数表示icebound打工挣来的收入,负数表示icebound消费的支出。数据保证不会出现 0​ 。

如果icebound本月总收入大于总支出,请你输出“icebound is happy.”;如果本月总收入等于总支出,请你输出“icebound is ok.";如果总收入小于总支出,请你输出"icebound is sad."。

输入:
第一行,有一个正整数n,代表账单有n行。

接下来有n行,每行一个整数,第i+1行整数aia_iai​

1≤n≤10001 \leq n \leq 10001≤n≤1000,∣ai∣≤1000\left| a_i \right|\leq 1000∣ai​∣≤1000∣,aia_iai​ 不为 0
输出:
输出一行。如果icebound本月总收入大于总支出,请你输出“icebound is happy.”;如果本月总收入等于总支出,请你输出“icebound is ok.";如果总收入小于总支出,请你输出"icebound is sad."。

题解:
题解:签到题,for循环不解释

AC代码

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
int main()
{int n, t;ll sum = 0;scanf("%d", &n);for(int i = 0; i < n; ++i) {scanf("%d", &t);sum += t;}if(sum > 0) puts("icebound is happy.");else if(sum == 0) puts("icebound is ok.");else puts("icebound is sad.");return 0;
}

Beautiful Array

题目描述:
Senior Pan has two positive integers x and y, and she calls an array is a beautiful array if and only if it satisfies the following conditions:

The elements in the array are integers.

The length of the array is exactly y.

The product of each element is exactly x.

Senior Pan wants you to help her calculate the number of beautiful arrays for different x and y.Two arrays A and BB are considered different if there exists a position i that Ai不等于Bi{A_i} 不等于 B_iAi​不等于Bi​
​For example, if x is 2 and y is 2, there are four beautiful arrays: [1, 2] [2, 1] [-1, -2], [-2, - 1].

The answer can be very large, so you can just tell her the number mod 109+710^9+7109+7
输入:
The first line is an integer T, denoting the number of test cases.
For the following T lines, each line contains two positive integers x and y
1≤T≤1051≤T≤10^51≤T≤105
x,y≤2∗1062*{10^6}2∗106
输出:
Output T lines, each line contains an integer, representing the number of beautiful array mod 109+710^9 + 7109+7

题解:CF 8693E 引用大神博客

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod = 1e9+7;
ll qpow(ll a,ll x){ll res=1;while (x){if(x&1)res=res*a%mod;a=a*a%mod;x/=2;}return res;
}
int prime[1005],cnt=0,vis[1005];
ll up[2000005],inv[2000005],down[2000005];
void init(){for(int i=2;i<=1001;i++){if(vis[i])continue;prime[cnt++]=i;for(int j=2*i;j<=1001;j+=i){vis[j]=1;}}down[0]=up[0]=inv[1]=1;for(int i=2;i<=2e6;i++){inv[i]=(mod-mod/i)*inv[mod%i]%mod;}for(int i=1;i<=2e6;i++){up[i]=up[i-1]*i%mod;down[i]=down[i-1]*inv[i]%mod;}
}
ll C(ll x,ll y){return up[x]*down[y]%mod*down[x-y]%mod;
}
int q,x,y;
int main(){//ios::sync_with_stdio(false);init();scanf("%d",&q);while (q--){scanf("%d%d",&x,&y);ll ans = 1;for(int i=0;prime[i]*prime[i]<=x&&i<cnt;i++){int cnt=0;while (x%prime[i]==0){x/=prime[i];cnt++;}if(cnt)ans=ans*C(y+cnt-1,cnt)%mod;}if(x!=1)ans=ans*y%mod;ans=ans*qpow(2,y-1)%mod;printf("%lld\n",ans);}
}

能力有限,剩下的题如果有大神会做可以私我,欢迎交流

2018年第二届河北省大学生程序设计竞赛相关推荐

  1. F-神殿-2018年第二届河北省大学生程序设计竞赛(位运算)

    icebound通过勤工俭学,攒了一小笔钱,于是他决定出国旅游.这天,icebound走进了一个神秘的神殿.神殿由八位守护者守卫,总共由 6464 64个门组成,每一道门后都有一个迷宫,迷宫的大小均为 ...

  2. 2018第二届河北省大学生程序设计竞赛题解

    icebound的账单 题目描述 icebound从小就有记账的习惯.又到了月末icebound统计资金状况的时候.icebound每个月除了不停的挥霍以外,有时他会良心发现,勤工俭学,因此会有一些微 ...

  3. 2017第一届河北省大学生程序设计竞赛题解

    超级密码 小明今年9岁了,最近迷上了设计密码!今天,他又设计了一套他认为很复杂的密码,并且称之为"超级密码". 说实话,这套所谓的"超级密码"其实并不难:对于一 ...

  4. 第 2 届河北省大学生程序设计竞赛(河北省赛)-Problem G. 520-题解

    传送门 Problem A. Mex Query Problem B. Nim Game Problem C. icebound 的账单 Problem G. 520 Problem H. 神殿 Pr ...

  5. 2017hbcpc(第一届河北省大学生程序设计竞赛)

    题目链接:http://newoj.acmclub.cn/contests/1484 还是太菜,好多题目还是不会. 文章目录 1841.超级密码 1842.斗地主 1843.考研 1844.自动签到机 ...

  6. 第二届河南省大学生程序设计竞赛 Dr.Kong的机器人

    Dr.Kong的机器人 Dr.Kong设计了一个可以前进或后退机器人,该机器人在每个位置i会得到一个移动步数的指令Ki (i=1,2„N),聪明的机器人自己会判断是要前进Ki步还是后退Ki步. 例如: ...

  7. 第 2 届河北省大学生程序设计竞赛(河北省赛)-Problem B. Nim Game-题解

    传送门 Problem A. Mex Query Problem B. Nim Game Problem C. icebound 的账单 Problem G. 520 Problem H. 神殿 Pr ...

  8. 第 2 届河北省大学生程序设计竞赛(河北省赛)-Problem H. 神殿-题解

    传送门 Problem A. Mex Query Problem B. Nim Game Problem C. icebound 的账单 Problem G. 520 Problem H. 神殿 Pr ...

  9. 2019河北省大学生程序设计竞赛(重现赛)

    B: 链接:https://ac.nowcoder.com/acm/contest/903/B 来源:牛客网 题目描述 Icebound hates math. But Imp loves math. ...

最新文章

  1. Fastlane- app自动编译、打包多个版本、上传到app store
  2. 御剑情缘服务器维护,御剑情缘10月31日安卓区部分服务器数据互通公告 10.31合服名称与时间[图]...
  3. VS+QT和qtcreator工程的互相转换
  4. 判断手机是否输入表情
  5. C/C++拾遗录--关于一个C语言小程序的分析
  6. ASP.NET MVC 自定义Razor视图WorkContext
  7. vue 生成二维码:vue-qr插件
  8. Julia: Dict类型 与 Symbol
  9. dda算法_C和C ++中的DDA线图绘制算法
  10. Separating Axis Theorem(分离轴理论)Raycast
  11. 紫书刷题记录 UVa1572 自组合
  12. php 前端 java培训哪个好,php培训、前端培训、java培训哪个好
  13. 2018前端走向全栈,Nodejs快速入门视频教程
  14. Unity UI界面的设计(完整版)
  15. Android版添加phonegap-百度社会化分享插件教程
  16. 深度学习与AI入门——追风记
  17. 获取门店出错(44)美团聚宝盆 门店映射报错
  18. EDA课设:CPU设计
  19. 第四篇:常用风控模型指标体系
  20. 【重识云原生】第四章云网络4.3.10.2节——VXLAN Overlay网络方案设计

热门文章

  1. dac0832控制电机驱动流程图_直流电机闭环调速课程设计上机指导
  2. Cover Letter
  3. 解决时间插件mobiscroll在使用过程中的一个小缺陷
  4. 百度O2O两条腿:百度地图和百度糯米
  5. opencv 使用hsv图抠绿色背景
  6. 语音合成论文优选:Unified Mandarin TTS Front-end Based on Distilled BERT Model
  7. js 获取url 参数
  8. Raid及其常见级别详解(附简单案例)
  9. 用matlab估计时延差,一种GNSS/INS松组合时延误差的估计及补偿方法与流程
  10. 基于python+mysql超市信息管理系统(附完整源代码)