本人现在比较菜,所以难免出现错误,文章中有不太恰当地方,还请大家指正。

是否因为出题人的简短题解而发愁?,是否看不懂出题人的变态模板标程?是否因为自己是小白而苦恼?来看这片文章,帮助你解决这些问题

题目已经全部补完,如果有收获请点个赞再走吧…

1001.收集金币

题目链接

算法:动态规划

状态dp思路:

f[i][0]表示前i个操作中一直没有跳的最大金币数量
f[i][1]表示前i个操作中已经跳过或者现在跳的最大金币数量

状态转移:
f[i][0]很简单只有一种状态
f[i][0]=f[i-1][0]+x

f[i][1]有两种状态可以转移过来
1.f[i][1]可以是第i个操作跳过即前i-1没有跳过即f[i-1][0]
2.前i-1已经跳过了,现在不需要跳过f[i-1][1]-x
所以
f[i][1]=max(f[i-1][0],max(f[i-1][1]-x,0ll))

最终状态
f[n][0]从头到尾一次都没跳过
f[n][1]只跳过一次的最大值

#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
#define int long long
const int N = 20010;
int f[N][2];
void solve()
{memset(f, 0, sizeof f);int n; cin >> n;for(int i = 1; i <= n; i ++){string op; cin >> op;int x; cin >> x;if(op == "LOST") x = -x;f[i][1] = max(max(0ll, f[i - 1][1] + x), f[i - 1][0]);f[i][0] = max(0ll, f[i - 1][0] + x);}cout << max(f[n][0], f[n][1]) << '\n';
}signed main()
{int T; cin >> T;while(T --) solve();
}

1002.使用技能

题目链接

算法:乘法逆元+快速幂

题意:这道题题目意思比较难懂,代码比较简单。由题意知序列的总数量是m^n的,我们需要先计算出所有序列的价值和,再除以序列总数量。
因为序列存在排序状态,因此每个序列都不一样。我们直接枚举释放x次技能的总数量,再加起来较为简便,首先需要从n个序列中挑选出x个位置即C(n,x)然后乘以m个技能,因为每个技能都可以,在把其他位置填满即可即(m-1)^(n-x)最后乘以每个价值x^2
公式为C(n,x)*m*(m-1)^(n-x)*x^2

#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
#define int long long
const int N = 100010, mod = 1e9 + 7;
int f[N], inf[N];
int qmi(int a,int b){int res=1;while(b){if(b&1)res=res*a%mod;a=a*a%mod;b>>=1;}return res;}
void init()
{f[0] = inf[0] = 1;for(int i = 1; i < N; i ++){f[i] = f[i-1] * i % mod;inf[i] = inf[i-1] * qmi(i, mod-2) % mod;}
}
int C(int a, int b)
{if(a < b)return 0;return f[a] % mod * inf[b] % mod * inf[a-b] % mod;
}
void solve()
{int n, m; cin >> n >> m;int res = 0 ;for(int i = 1; i <= n; i ++)res =  (res + m * i % mod * i % mod * C(n, i) % mod * qmi(m - 1, n - i) % mod ) % mod;  for(int i = 1; i <= n; i ++)res = res * qmi(m, mod - 2) % mod;cout << res % mod << '\n';
}signed main()
{init();int T; cin >> T;while(T --) solve();
}

1003.欢度佳节

题目链接

算法:位运算+暴搜

思路:题目求占领的最大方块,所以筛子数值就假设每次一定是6,仔细看题,糖果库存大于某个格子的数值,且这个格子与你占领的格子相邻,那么你可以选择占领这个格子这里的大于容易理所应当的看成大于等于,所以每个格子需要的掷投数量就是a[i]=a[i]/6+1

本题需要先把输入的一维数据转化为二维,用方位数组dx【】,dy【】进行每个方位判断,之后根据位运算,再把二维转化为一维。

因为是17个格子,所以2^17不会超时,可以暴力来做,用二进制枚举每一个状态,是1则表示会到这个格子上,0则反之,每个二进制数字再进行判断是否符合题目要求,如果符合找出二进制中1的个数,每次更新,求最大值即可。

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
#define int long long
const int N = 100010, mod = 1e9 + 7;
int x[]={1,1,1,1,2,2,2,3,3,3,4,4,4,5,5,5,5};
int y[]={1,2,4,5,2,3,4,2,3,4,2,3,4,1,2,4,5};
int dx[4] = {1, 0, -1, 0}, dy[4] = {0, 1, 0, -1};int mp[10][10];
int n, w[N];
int arrive, cnt;
bool dfs(int x, int y, int state)
{if(arrive == state && cnt <= n) return true;int id = mp[x][y];if(id == -1 || !(state >> id & 1) || (arrive >> id & 1)) return false;arrive |= 1 << id;cnt += w[id];for(int i = 0; i < 4; i ++)if(dfs(x + dx[i], y + dy[i], state)) return true;return false;
}void solve()
{for(int i = 0; i < 17; i ++) cin >> w[i], w[i] = (w[i] + 5) / 6;cin >> n;int res = 0;for(int i = 0; i < 1 << 17; i ++){//第13个数字是出发点,如果状态中没有则直接continueif((i >> 13 & 1) == 0) continue;//这里的arrive用于判断路径的连通性和进行判重,不再走原来走过的路arrive = 0, cnt = 0;if(dfs(x[13], y[13], i)) res = max(res, (int)__builtin_popcount(i));}cout << res << '\n';
}signed main()
{memset(mp, -1, sizeof mp);for(int i = 0; i < 17; i ++)mp[x[i]][y[i]] = i;int T; cin >> T;while(T --) solve();
}

1004. 五个小时卷积神经网络从入门到入土

题目链接

阅读理解 + 找性质

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
#define int long long
const int N = 100010, mod = 998244353;
int qmi(int a,int b){int res=1;while(b){if(b&1)res=res*a%mod;a=a*a%mod;b>>=1;}return res;}void solve()
{int sum1 = 0, sum2 = 0;int n, m; cin >> n >> m;for(int i = 0; i < 3; i ++)for(int j = 0, x; j < 3; j ++)cin >> x, sum1 += x;for(int i = 0; i < n; i ++){string s; cin >> s;for(int j = 0; j < n; j ++)sum2 += s[j] == '1';}int inv = qmi(4, mod - 2);int res = sum2 * qmi(sum1 * inv % mod, m) % mod;cout << res << '\n';
}signed main()
{   int T; cin >> T;while(T --) solve();
}

1005.闯关游戏

题目链接

算法:01背包+贪心

思路:这道题比较巧妙,看起来像分组背包,但其实不是,先根据贪心的思路进行判断,把一个空间更小的数放进背包,在把差值跑一边01背包,非常巧妙

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
#define int long long
const int N = 6010;int f[N];
void solve()
{memset(f, 0, sizeof f);int n, m; cin >> n >> m;int res = 0, sw = 0, sv = 0;for(int i = 1; i <= n; i ++){int v1, w1, v2, w2;cin >> v1 >> w1 >> v2 >> w2;if(v1 > v2) swap(v1, v2), swap(w1, w2);sw += w1;sv += v1;// 这里不能用break,因为要把剩余数据输进去if(sv > m) continue;int v = v2 - v1, w = w2 - w1;for(int j = m - sv; j >= v; j --)f[j] = max(f[j],f[j - v] + w);res = max(res, sw + f[m - sv]);}cout << res << '\n';
}signed main()
{   int T; cin >> T;while(T --) solve();
}

1006.军训

题目链接

算法:打表+玄学盲猜+数学+注意卡常

本题解摘自:_ sky123 _
原文链接:https://sky123.blog.csdn.net/article/details/121102090


#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
#define int long long
int n;
bool check(int fn)
{for(int a = 0; a <= fn / 2; a ++){int b = fn - a; for(int x = 1; x * x + a * x < n; x ++){int s = b * b + 4 * (n - x * x - a * x);int qs = sqrt(s);if(qs * qs == s && (qs - b) % 2 == 0) return true;}}return false;
}void solve()
{cin >> n;if (n == 551189743 || n == 656865901 || n == 845198527) {cout << 16 << "\n";return ;}if (n == 608733239) {cout << 17 << "\n";return ;}int res = 0;while(!check(res))res ++ ;cout << res << '\n';
}signed main()
{int T; cin>>T;while(T--) solve();
}

1007.数"X"

题目链接

本题解摘自:_ sky123 _
原文链接:https://blog.csdn.net/qq_45323960/article/details/121102930

单独考虑 “X” 两个方向,对于每个方向,将该方向上的元素组成一个序列,记录每个元素下一次出现的位置,然后二分枚举范围,使得该范围中每个元素下一次都只能出现在范围外。像这样枚举中心点累加即可得到答案,时间复杂度为 O ( n^2 log ⁡ n ) 。

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
#define int long long
const int N = 1010;struct ST
{int dp[N][10];void init(int a[], int n){for(int i = 1; i <= n; i ++) dp[i][0] = a[i - 1];for(int j = 1; (1 << j) <= n; j ++) for(int i = 1; i + (1 << j) - 1 <= n; i ++)dp[i][j] = min(dp[i][j - 1], dp[i + (1 << (j - 1))][j - 1]);}int ask(int l, int r){int k = __lg(r - l + 1);return min(dp[l + 1][k], dp[r - (1 << k) + 2][k]);}
} S;int a[N][N], n, T;
vector<int> tmp;
vector<pair<int, int>> pos;
int nx[N], cp[N*N];
int cnt[N][N];void solve()
{int m = tmp.size();for(auto x : tmp) cp[x] = m;for(int j = m - 1; j >= 0; j --)nx[j] = cp[tmp[j]], cp[tmp[j]] = j;S.init(nx, m);for(int i = 0; i < m; i ++){int l = 1, r = min(i + 1, m - i);while(l < r){int mid = (l + r + 1) >> 1;S.ask(i - mid + 1, i + mid - 1) <= i + mid - 1 ? (r = mid - 1) : (l = mid); }cnt[pos[i].first][pos[i].second] = min(l, cnt[pos[i].first][pos[i].second]);}
}signed main()
{ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);cin >> T;while(T --){cin >> n;for(int i = 1; i <= n; i ++)for(int j = 1; j <= n; j ++)cin >> a[i][j], cnt[i][j] = n;for(int i = 1; i <= n; i ++){pos.clear(), tmp.clear();for(int x = 1, y = i; y <= n; x ++, y ++)pos.push_back({x,y}),tmp.push_back(a[x][y]);solve();}for(int i = 1; i <= n; i ++){pos.clear(), tmp.clear();for(int x = i, y = 1; x <= n; x ++, y ++)pos.push_back({x,y}),tmp.push_back(a[x][y]);solve();}for(int i = 1; i <= n; i ++){pos.clear(), tmp.clear();for(int x = 1, y = i; y >= 1; x ++, y --)pos.push_back({x,y}),tmp.push_back(a[x][y]);solve();}for(int i = 1; i <= n; i ++){pos.clear(), tmp.clear();for(int x = i, y = n; x <= n; x ++, y --)pos.push_back({x,y}),tmp.push_back(a[x][y]);solve();}int res = 0;for(int i = 1; i <= n; i ++)for(int j = 1; j <= n; j ++)res += cnt[i][j];cout << res << '\n';}
}

1008.小y爱数数

题目链接

算法:快速幂+dp+逆元

这是一个复杂度较高地做法,复杂度为10nlog(n)
思想:最简单思想是两层循环枚举算出余数为k的方法数,再除以n^2就是概率,但本题时间为300ms必然超时,我们可以采取类似埃式筛法筛质数的思想把每个余数为k的数给筛出来
用一个二维数组存储f[i][j] i即余数,j即符合要求的数,把f[i][j]预处理出来,用的时候直接使用就可以了,详细请看代码

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
#define int long long
const int N = 100010, mod = 23333;
int f[12][N];int qmi(int a,int b){int res=1;while(b){if(b&1)res=res*a%mod;a=a*a%mod;b>>=1;}return res%mod;}signed main()
{ios::sync_with_stdio(false);//预处理for(int i = 0; i <= 10; i ++){//这里的j指的是y,k指的是倍数,类似于埃式筛法把y的k倍+i的数全部筛出来for(int j = i + 1; j <= 1e5; j ++)for(int k = 1; k * j + i <= 1e5; k ++)f[i][k * j + i] ++;//计算每个余数的方案和for(int j = 1; j <= 1e5; j ++) f[i][j] += f[i][j - 1];}int T; cin >> T;int res = 0;while(T --){int n, k; cin >> n >> k;int ans = f[k][n];//因为预处理时从x大于k的开始了所以这里需要加上那些x等于k的且y大于k的 所以加上n-k个if(k != 0) ans += max(n - k, 0ll);int state = ans * qmi((n * n) % mod, mod - 2) % mod;state = (state + mod) % mod;res=res ^ state;}cout << res << endl;}

1009.神奇的魔法

题目链接

算法:小根堆的维护+状态枚举

题意:本题看着好像是背包问题,但是和背包毫无关联,题意为有多个背包,每个背包有限制,最少拿的数量l[N]和最多拿的数量r[N],因此题目中一共有所有r[i]-l[i]之和+1种状态(全部刚好满足最低l[i]的一种状态),每种状态求最大值,在异或起来就是答案.

算法:如何求每种状态的最大值呢,用一个动态的最小堆维护就好了。

主要思路:考虑选取物品集合确定的时候一定优先选择价值大的物品,所以我们可以考虑拿一个堆维护当前选择价值翻倍的物品,如果是堆中物品 则直接把物品插入堆,否则若物品价值小于堆中最小值则替换。

#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
#define int long long
const int N = 510;
priority_queue<int, vector<int>, greater<int>> heap;
int n, m, k, idx = 0;
int state = 0, res = 0;
int a[N][N], l[N], r[N];
vector<int>q;//维护一个动态小根堆
void check(int x)
{if(heap.size() < k){heap.push(x);state += 2 * x;}else if(heap.top() < x){state -= heap.top();state += 2 * x;heap.pop();heap.push(x);}else state += x;
}signed main()
{int T; cin >> T;while(T--){//每组数据记得清空while(heap.size()) heap.pop();idx = 0, state = 0, res = 0;q.clear();cin >> n >> m >> k;for(int i = 1; i <= n; i ++){for(int j = 1; j <= m; j ++)cin >> a[i][j];sort(a[i] + 1, a[i] + m + 1, greater<int>());}for(int i = 1; i <= n; i ++){cin >> l[i] >> r[i];//idx统计状态的数量idx += r[i] - l[i];for(int j = 1; j <= l[i]; j ++) check(a[i][j]);//把这idx个状态用vector存储起来for(int j = l[i] + 1; j <= r[i]; j ++) q.push_back(a[i][j]);}//从大到小排序sort(q.begin(), q.end(), greater<int>());res = state;for(int i = 0; i < idx; i ++){check(q[i]);//每种状态异或起来res ^= state;}cout << res << endl;}
}

1010.小凯的书架

解法一:概率暴力可过,但感觉这完全是数据水,不是正解,追求正解的请看解法二。

直接暴力每次枚举到一个位置就去前边找大于它的第k个数

复杂度O(nk)

题目链接

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 300010;
int a[N];
int main()
{int T; cin>>T;while(T --){int n, k; cin >> n >> k;for(int i = 0; i < n; i ++) cin >> a[i];for(int i = 0; i < n; i ++){if(i<k){cout << "-1" << '\n';continue;}int cnt = 0;for(int j = i - 1; j >= 0; j --){if(a[j] > a[i]) cnt ++;if(cnt == k){cout << a[j] << '\n';break;}}if(cnt < k) cout << -1 << '\n';}}
}

解法二:

非常感谢_sky123_ 大佬给了我题解和思路
详情请看代码,代码写的比较简洁。
主要思路:首先用一个下标数组id记录每个书的高度的初始位置的下标,然后按照书的高度,将这些书高度的初始下标id数组进行排序,这时的id数组已经被打乱,其顺序是按照书的高度排列的,然后从前往后遍历下标数组,找出前面比当前值小的下标的数量,如果数量小于k则直接答案下标位置加入-1,否则用二分从前往后找到总数量-k+1那个位置,将下标记录答案中。

算法:树状数组+二分

树状数组也卡常,不要用cin和cout,加了O2优化也会TLE 。。。。

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 200010;
int tr[N], a[N], id[N], res[N];
int n, k;
int lowbit(int x)
{return x & -x;
}
void add(int x,int v)
{for(int i = x; i <= n; i += lowbit(i)) tr[i] += v;
}
int query(int r)
{int res = 0;for(int i = r; i > 0; i -= lowbit(i)) res += tr[i];return res;
}
int main()
{int T; scanf("%d",&T);while(T--){memset(tr, 0, sizeof tr);memset(res, 0, sizeof res);scanf("%d %d",&n,&k);for(int i = 1; i <= n; i ++) scanf("%d", &a[i]);for(int i = 1; i <= n; i ++) id[i] = i;//这里是C++的匿名函数,没见过的自行百度sort(id + 1, id + n + 1,[&](int i,int j){return a[i] > a[j]; });for(int i = 1; i <= n; i ++){int num = query(id[i]);if(num < k){res[id[i]] = -1;add(id[i], 1);continue;}int pre = num - k + 1, l = 1, r = id[i] - 1;while(l < r){int mid = l + r >> 1;if(query(mid) < pre) l = mid + 1;else r = mid;}res[id[i]] = a[r];add(id[i], 1);}for(int i = 1; i <= n; i ++) printf("%d\n",res[i]);}
}

1011.未成年人之友

纯签到题

题目链接

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;int main()
{int T; cin >> T;while(T --){string s;int n, h, m; cin >> n >> s;scanf("%d:%d", &h, &m);if(n >= 18){cout << "Yes" << endl;continue;}if(s == "Fri" || s == "Sat" || s == "Sun"){if(h == 20 && m >= 0 && m <= 59) cout << "Yes" << endl;else cout << "No" << endl;}else cout << "No" << endl;}
}

1012.黑曜石

算法:模拟一下即可

只有水和岩浆相邻,或者水和岩浆中间只隔了空气,才可能生成新的黑曜石。因此答案为 一开始的黑曜石数 + 按高度排序后水和岩浆相邻的个数即为答案。

题目链接

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N=100010;
struct Node
{int h, type;bool operator < (const Node & H) const{return h < H.h;}
}a[N];
int main()
{int T; cin >> T;while(T--){int n; cin >> n;int res = 0;for(int i = 0; i < n; i ++)cin >> a[i].type >> a[i].h;sort(a, a + n);for(int i = 0; i + 1 < n; i ++){if((a[i].type == 1 && a[i + 1].type == 2) || (a[i].type == 2 && a[i + 1].type == 1))res ++;if(a[i].type == 3)res ++;}if(a[n-1].type == 3) res ++;cout << res << endl;}
}

题目已经完全补完,1007和1006参照_sky123_大佬题解,如果有收获请点个赞再走吧。

2021卓见杯第三届CCPC河南省省赛所有题超详细题解附加榜单真题解析,简单代码+详细注释+思想,要看的,补题的速速点进来 2021 10.30相关推荐

  1. 第五届河南省CCPC河南省省赛题解+复盘

    第五届河南省CCPC河南省省赛题解+复盘 今年省赛相当有意思的一点,是20级第一次线下省赛,对于部分队也可能是最后一次,看队名就能看出来很多 考研就业的选手,一群老年人在这PK,氛围挺不错. A - ...

  2. 第三届粤港澳大湾区生物科技企业50强榜单揭晓

    由中创产业研究院.毕马威中国主办,广东医谷承办的第三届粤港澳大湾区生物科技创新企业50强颁奖典礼暨大湾区生物科技创新发展峰会日前在广州南沙举办. 50强榜单发布  广深约占比八成 在50强榜单中,聚集 ...

  3. “卓见杯”2020年河南省第二届CCPC大学生程序设计竞赛 J.二进制与、平方和

    2699: 二进制与.平方和 时间限制: 3 Sec  内存限制: 512 MB 提交: 58  解决: 10 [状态] [讨论版] [提交] [命题人:admin] 题目描述 请你维护一个长度为 n ...

  4. 既约分数蓝桥杯c语言,2021蓝桥杯C++第二届省赛

    负载平衡 题目描述 有 \\(n\\) 台计算机,第 \\(i\\) 台计算机的运算能力为 \\(v_i\\). 有一系列的任务被指派到各个计算机上,第 \\(i\\) 个任务在 \\(a_i\\) ...

  5. 2021河南省第十三届ACM/icpc大学生程序设计竞赛榜单

  6. 第十四届中国大学生服务外包创新创业大赛 #40道赛题 #保研加分 #教育部榜单赛事

    CompHub 实时聚合多平台的数据类(Kaggle.天池-)和OJ类(Leetcode.牛客-)比赛.本账号会推送最新的比赛消息,欢迎关注! 更多比赛信息见 CompHub主页[1] 以下内容摘自比 ...

  7. redis的redis.config文件配置与内容+10.30日之前的总结

    参考博客:redis.conf的一些配置+密码的设置(mac)+个人总结_雾喔的博客-CSDN博客_redis密码配置文件 这个是初始的redis.config的内容 # Redis configur ...

  8. 蓝桥杯第三届初赛“自动售水机”设计任务书

    文章目录 蓝桥杯第三届初赛"自动售水机"设计任务书 Author:Luis Time:2022-04-06 Version:v1.0 说明 功能简述 具体代码 iic.c iic. ...

  9. 2021/10/30的1+X大数据Java答案

    2021/10/30 步骤二 public Member() { }public Member(String name,String pwd,float score,int rank) {this.n ...

最新文章

  1. VOC2007基本信息
  2. 【概率论与数理统计】假设检验
  3. 理工科毕业设计献礼,MATLAB从入门到精通之矩阵是如何实现寻访与赋值的
  4. hdu 5402 Travelling Salesman Problem (技巧,未写完)
  5. 机器学习第二回——矩阵部分总结
  6. 20155204《网络对抗》Exp 6 信息搜集与漏洞扫描
  7. html 的scor属性,HTML DOM scrollTop 属性
  8. http 传输原理及格式
  9. Forbidden什么意思
  10. 2019互联网BATJ等大厂中秋礼盒大PK
  11. 单词拆分(动态规划)
  12. Viterbi-Algorithm(维特比)算法
  13. (C++)将8000秒换算成小时分钟秒的形式
  14. 一文搞懂 STL 中 deque 与 hashtab 的底层实现
  15. Android studio gradle编译失败问题汇总
  16. MATLAB遗传算法工具箱安装包及安装方法(图解)
  17. STM32贪吃蛇实现
  18. 仿网易云音乐源码html5
  19. CCD摄像机主要技术参数解释
  20. 二维图像的傅立叶变换

热门文章

  1. python计算p-value
  2. Spring4.x源码解析:JDK动态代理成生成代理对象源码
  3. SmallestWidth一种非常好用的Android屏幕适配
  4. EsgynDB之TRIM函数
  5. 孩子上幼儿园中班,身边同学都在报英语班,这么小的孩子有必要吗?
  6. 一个函数有多少行代码比较合适?
  7. 哪些C语言编译器支持easyX库,【C语言小白入门到精通】EasyX 是什么?EasyX图形库安装使用方法...
  8. 编写病毒程序取款700余万,华夏银行一技术处长被捕受审
  9. TCGA Copy Number Portal:肿瘤拷贝数变异数据中心
  10. C语言:从键盘输入一个字符串str,统计str中小写字母a到z共26个字母的个数(个数为0的不显示,其它字符不统计)。