「团队训练赛」2021 Jiangsu Collegiate Programming Contest题解
A - Spring Couplets
题目描述:
写春联,满足所需的平仄关系
如果上联的一个字是平的,那下联对应的字必须是仄的
相同的,如果上联的一个字是仄的,那下联对应的字必须是平的
而且上联的最后一个字必须是仄的
问你春联是否合法
思路:
就把数搞出来以后,挨个判断就行
#include <bits/stdc++.h>
using namespace std;#define endl '\n'
#define inf 0x3f3f3f3f
#define mod 1000000007
#define sd(n) scanf("%d",&n)
#define sdd(n,m) scanf("%d %d",&n,&m)
#define m_p(a,b) make_pair(a, b)
#define mem(a,b) memset((a),(b),sizeof(a))
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define io ios::sync_with_stdio(false); cin.tie(0); cout.tie(0)
#define debug(a) cout << "Debuging...|" << #a << ": " << a << "\n";
typedef long long ll;
typedef pair <int,int> pii;#define MAX 300000 + 50
int n, m, k, op;
string s;
int ar[MAX];
int br[MAX];
void work(){cin >> n;for(int i = 1; i <= n; ++i){cin >> s;ar[i] = s.back() - '0';}for(int i = 1; i <= n; ++i){cin >> s;br[i] = s.back() - '0';}for(int i = 1; i < n; ++i){if(ar[i] == 1 || ar[i] == 2){if(br[i] == 3 || br[i] == 4)continue;else {cout << "NO\n";return;}}else if(ar[i] == 3 || ar[i] == 4){if(br[i] == 1 || br[i] == 2)continue;else {cout << "NO\n";return;}}}if(ar[n] == 3 || ar[n] == 4){if(br[n] == 1 || br[n] == 2){cout << "YES\n";return;}}cout << "NO\n";
}int main(){io;int tt;cin>>tt;for(int _t = 1; _t <= tt; ++_t){work();}return 0;
}
C - Magical Rearrangement
题目描述:
给你若干个数字,问能凑出来的最小的数字是多少
如果不行的话,输出-1
思路:
先考虑-1的情况,用
maxn
记录数量最大的数字,用sum
记录除maxn
的数字外的数字的和
- 如果
maxn
是0,由于第一位不能放0的限制,则必须满足sum >= maxn
- 如果
maxn
不是0,因为第一位可以放非0的数字,所以只需要满足sum >= maxn - 1
即可然后我们需要一个函数
f(x)
,表示上一位选择x
时,下一位可以选择的最小的数,我们只需要从0
到9
去枚举每一位,判断如果这一位选这个数时,剩下的数字能否满足条件的摆放,判断条件就和上面的几乎一样
//Work by: Chelsea
#include <bits/stdc++.h>
using namespace std;#define endl '\n'
#define inf 0x3f3f3f3f
#define mod 1000000007
#define sd(n) scanf("%d",&n)
#define sdd(n,m) scanf("%d %d",&n,&m)
#define m_p(a,b) make_pair(a, b)
#define mem(a,b) memset((a),(b),sizeof(a))
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define io ios::sync_with_stdio(false); cin.tie(0); cout.tie(0)
#define debug(a) cout << "Debuging...|" << #a << ": " << a << "\n";
typedef long long ll;
typedef pair <int,int> pii;#define MAX 300000 + 50
int n, m, k, op;
int tr[MAX];int update(int x){for(int i = 0; i < 10; ++i){if(!tr[i] || i == x)continue;--tr[i];int p = 0, maxn = 0, sum = 0;for(int j = 0; j <= 9; ++j){sum += tr[j];if(maxn < tr[j]){maxn = tr[j];p = j;}}sum -= maxn;if(p == i && maxn > sum){++tr[i];continue;}if(p != i && maxn > sum + 1){++tr[i];continue;}return i;}return -1;
}void work(){int sum = 0;int p = 0, maxn = 0;for(int i = 0; i <= 9; ++i){cin >> tr[i];if(maxn < tr[i]){maxn = tr[i];p = i;}sum += tr[i];}sum -= maxn;if(sum == 0 && tr[0] == 1){cout << 0 << endl;return;}if(p == 0 && sum < maxn){cout << -1 << endl;return;}if(p != 0 && sum < maxn - 1){cout << -1 << endl;return;}string ans = "";int num = update(0);while(num >= 0){ans += (char)(num + '0');num = update(num);}cout << ans << endl;
}int main(){int tt;cin>>tt;for(int _t = 1; _t <= tt; ++_t){work();}return 0;
}
D - Pattern Lock
题目描述:
给你一个
n*m
的点阵,你需要用一笔画的形式连接n*m
个点,并输出n*m
个点的坐标,表示连接顺序,需要满足如下的条件:
- 连接的点只能出现一次
- 任意两条相邻的边的夹角必须是锐角
- 任意两个相邻的点之间不能存在别的点,即
(1, 1),(3, 3)
之间不能直接连接,因为中间存在一个(2, 2)
思路:
很有意思的一个题
需要根据
n
和m
的奇偶来分类讨论
对于
n
是偶数的情况很好说,只需要按下图来进行连接即可对于
n
是奇数
如果
m
是偶数,那也很好连,只需要像n是偶数的那样,不过需要把图倒过来如果
m
是奇数,就不是很好搞,需要把奇数的拆成三部分一个
偶*奇
+3 * 3
+3 * 偶
所以我们只需要搞一个横着的,一个竖着的,还一个
3 * 3
的就行,写起来蛮简单的
#include <bits/stdc++.h>
using namespace std;#define endl '\n'
#define inf 0x3f3f3f3f
#define mod7 1000000007
#define mod9 998244353
#define m_p(a,b) make_pair(a, b)
#define mem(a,b) memset((a),(b),sizeof(a))
#define io ios::sync_with_stdio(false); cin.tie(0); cout.tie(0)
#define debug(a) cout << "Debuging...|" << #a << ": " << a << "\n";
typedef long long ll;
typedef pair <int,int> pii;
#define y1 y114514
#define MAX 300000 + 50
int n, m, k, x;vector<pii>ans;void calleft_rigth(int x1, int y1, int x2, int y2){ans.push_back(m_p(x1, y1));for(int i = 1; i <= y2 - y1; ++i){ans.push_back(m_p(x1, y1 + i));ans.push_back(m_p(x2, y1 + i - 1));}ans.push_back(m_p(x2, y2));
}void calup_down(int x1, int y1, int x2, int y2){ans.push_back(m_p(x1, y1));for(int i = 1; i <= x2 - x1; ++i){ans.push_back(m_p(x1 + i, y1));ans.push_back(m_p(x1 + i - 1, y2));}ans.push_back(m_p(x2, y2));
}void cal_3(int x, int y){ans.push_back(m_p(x, y));ans.push_back(m_p(x, y + 1));ans.push_back(m_p(x + 2, y));ans.push_back(m_p(x + 1, y + 2));ans.push_back(m_p(x + 2, y + 2));ans.push_back(m_p(x + 1, y + 1));ans.push_back(m_p(x + 2, y + 1));ans.push_back(m_p(x, y + 2));ans.push_back(m_p(x + 1, y));
}void work(){cin >> n >> m;if(n % 2 == 0){for(int i = 1; i <= n; i += 2){calleft_rigth(i, 1, i + 1, m);}}else {if(m % 2 == 0){for(int i = 1; i <= m; i += 2){calup_down(1, i, n, i + 1);}}else{for(int i = 1; i <= n - 3; i += 2){calleft_rigth(i, 1, i + 1, m);}cal_3(n - 2, 1);for(int i = 4; i <= m; i += 2){calup_down(n - 2, i, n, i + 1);}}}for(auto [x, y] : ans)cout << x << ' ' << y << endl;}int main(){io;work();return 0;
}
I - Fake Walsh Transform
题目描述:
输入
n, m
,你可以从0
到 2n2^n2n 中选择若干个数,使的这些数异或后等于m
,问最多可以选多少个数
思路:
- n = 1
- m = 0, 输出2
- m = 1, 输出1
- n > 1
- m = 0,输出 2n2^n2n
- m = 1,输出 2n−12 ^ n-12n−1
//Work by: Chelsea
#include <bits/stdc++.h>
using namespace std;#define endl '\n'
#define inf 0x3f3f3f3f
#define mod 1000000007
#define sd(n) scanf("%d",&n)
#define sdd(n,m) scanf("%d %d",&n,&m)
#define m_p(a,b) make_pair(a, b)
#define mem(a,b) memset((a),(b),sizeof(a))
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define io ios::sync_with_stdio(false); cin.tie(0); cout.tie(0)
#define debug(a) cout << "Debuging...|" << #a << ": " << a << "\n";
typedef long long ll;
typedef pair <int,int> pii;#define MAX 300000 + 50
ll n, m;void work(){cin >> n >> m;if(n == 1){if(m == 0)cout << 1 << endl;else cout << 2 << endl;}else if(m == 0){cout << (1ll << n) << endl;}else{cout << (1ll << n) - 1 << endl;}
}int main(){int tt;cin>>tt;for(int _t = 1; _t <= tt; ++_t){work();}return 0;
}
J - Anti-merge
题目描述:
给你一个
n * m
的矩阵,每个点都有一个权值,合并矩阵的方法是这样的:
- 先每一列的选择权值相同的点,合并成一个点
- 再每一行的看,选择权值相同的点,合并成一个点,如果合并列的时候合并出相邻的两个起点终点相同的权值相同的两个点,则这两个点也可以合并成一个新的点
现在你需要给矩阵上的每个点都加一个标签,这样合并的时候需要满足权值和标签完全相同的来合并,问要使的整个矩阵的任意一个点都不被合并,最少需要几种标签,在此基础上,最小有几个点需要打上标签,点可以不存在标签,如果不存在标签,则默认标签的值为0,这是不计入答案的数量
思路:
其实读懂以后会发现这是个很简单的题,我们只需要一种标签就行
对于每个连通块,我们去01染色就行,染出黑色和白色后,看看哪个数量少,就把数量少的打上标签,数量多的就当不打标签,这样数量就是最小的
#include <bits/stdc++.h>
using namespace std;#define endl '\n'
#define inf 0x3f3f3f3f
#define mod7 1000000007
#define mod9 998244353
#define m_p(a,b) make_pair(a, b)
#define mem(a,b) memset((a),(b),sizeof(a))
#define io ios::sync_with_stdio(false); cin.tie(0); cout.tie(0)
#define debug(a) cout << "Debuging...|" << #a << ": " << a << "\n";
typedef long long ll;
typedef pair <int,int> pii;#define MAX 300000 + 50
int n, m, k, x;
int tr[505][505];
bool vis[505][505];
vector<pii>ans;
vector<pii>num0, num1;
int dx[] = {1, 0, -1, 0};
int dy[] = {0, 1, 0, -1};bool judge(int x, int y){if(x > n || x < 1 || y > m || y < 1)return false;else if(vis[x][y])return false;return true;
}void dfs(int x, int y, int c){vis[x][y] = 1;if(c == 0)num0.push_back(m_p(x, y));else num1.push_back(m_p(x, y));for(int i = 0; i < 4; ++i){int xx = x + dx[i];int yy = y + dy[i];if(judge(xx, yy) && tr[x][y] == tr[xx][yy]){dfs(xx, yy, c ^ 1);}}
}void work(){cin >> n >> m;for(int i = 1; i <= n; ++i){for(int j = 1; j <= m; ++j){cin >> tr[i][j];}}for(int i = 1; i <= n; ++i){for(int j = 1; j <= m; ++j){if(!vis[i][j]){num0.clear();num1.clear();dfs(i, j, 0);if(num0.size() >= num1.size()){for(auto [x, y] : num1){ans.push_back(m_p(x, y));}}else{for(auto [x, y] : num0){ans.push_back(m_p(x, y));}}}}}if(ans.size() == 0)cout << 0 << ' ';else cout << 1 << ' ';cout << ans.size() << endl;for(auto [x, y] : ans)cout << x << ' ' << y << ' ' << 1 << endl;}int main(){io;work();return 0;
}
K - Longest Continuous 1
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<string>
#include<vector>
using namespace std;
int t;
long long n;
long long sum=0;
int ans;
int main()
{scanf("%d",&t);while(t--){scanf("%lld",&n);if(n==1){printf("0\n");continue;}sum=1;ans=1;for(int i=1;i<=50;++i){sum+=(1ll<<(i-1))*i;if(n>=sum+1) ans=i+1;else break;}printf("%d\n",ans);}return 0;
}
日常赛后小作文
还是因为疫情,没法在集训室统一实行3人1机,就还是打的三人三机。
我们队伍签到挺快的,我和djk一起开A题,yj去开K题,我上来没怎么看题面,直接看样例猜题意,发现是个春联的平仄问题,问了djk一句谁是平谁是仄以后就直接写了,7分钟的时候就过了
然后我和djk就去看I
题,这个题当时太急了,没考虑仔细,wa了3发,后来才改出来,我的锅,都怪我没事瞎试,在比赛最开始贡献了60发的罚时,下次比赛在前期一定会多检查检查再交,尽量1a
我和djk又开C
,我发现这个题有0的存在不好写,感觉有点模拟的意思,就不想写,就去看J
题
这个时候yj过了K
题,我们就让他去写C
我和djk开J
,读完题想了一会就想到了01染色,把数量小的记为答案,然后我火速写了就过了,这个时候大概是1小时17分
我写J的时候,djk去读D了,我过了J后我俩就开始讨论怎么D,开始他糊了个假做法给我,我直接去敲了,敲了个头的时候,yj过了C,djk就把题意和思路讲个yj,yj一眼就发现这个思路的问题,得亏发现的早,不然就白写了
我们三就开始疯狂画图讨论,讨论了有快一个小时,画了写写了画,终于讨论出来四种情况改怎么写,然后两个人都写了,都wa了,我和djk讨论觉得一致没问题,甚至怀疑到数据有问题,笑死,后来我改了一下3 * 3的矩阵构造方法,就过了,然后就发现了我们的一个小问题,由于我们俩都是用的我画出来的图写的,所以俩人都写挂了,这个时候大概是赛后的3点45,打完就下班了
「团队训练赛」2021 Jiangsu Collegiate Programming Contest题解相关推荐
- 2021 Jiangsu Collegiate Programming Contest部分题解
2021 Jiangsu Collegiate Programming Contest 目录 A. Spring Couplets C. Magical Rearrangement I. Fake W ...
- 「团队训练赛」The 14th Jilin Provincial Collegiate Programming Contest「ABCEFGJLM」
The 14th Jilin Provincial Collegiate Programming Contest A. Chord 题目描述: 给出C, C#, D, D#, E, F, F#, G, ...
- 2021 Jiangsu Collegiate Programming Contest——K. Longest Continuous 1
题目地址https://codeforces.com/gym/103495/problem/K 题目解析 题目 思路 代码 题目 Example: 4 1 2 3 4 output: 0 1 2 2 ...
- 2021 Jiangsu Collegiate Programming Contest F. Jumping Monkey II 树剖+线段树
F. Jumping Monkey II 题意: 给你 n = 2 e 5 n=2e5 n=2e5的一棵树,每个点有点权 a [ i ] < = 1 e 9 a[i]<=1e9 a[i]& ...
- The 15th Heilongjiang Provincial Collegiate Programming Contest题解 gym102803
The 15th Heilongjiang Provincial Collegiate Programming Contest题解 gym102803 前言 题目 A. August B. Bills ...
- 2020 Jiangsu Collegiate Programming Contest
比赛链接 题号 题目 难易 考点 Gym 102875A Array 难 线段树,欧拉降幂 Gym 102875B Building Blocks Gym 102875C Cats 签到题 贪心,思维 ...
- 2022 Jiangsu Collegiate Programming Contest I. Cutting Suffix
题目链接 Examples input aa Output 1 input ab Output 0 题目大意: 后缀i是字符串从第i个字符开始到最后的字符字串 定义Wi,j是字符串 后缀i和后缀j的公 ...
- 2022 Jiangsu Collegiate Programming Contest - J. Balanced Tree
L. Collecting Diamonds 题目描述 A binary tree T is called super balanced if T is empty or satisfies the ...
- 2015 Syrian Private Universities Collegiate Programming Contest 题解
题目在这里>_< 发现这场比赛在网上没有完整的题解,甚至连题目代码都没人贴出来(大概是因为题目太水了吧...).所以宝宝就来写个题解,也就当作成长记录了233333 A. Window 题 ...
最新文章
- ad hoc是什么的简称_签名后的App安装时出现安装失败是什么原因?如何解决?
- 一级计算机考试题库25套答案,全国计算机等级考试一级试题及答案(25套)..doc
- 字符设备驱动开发流程详解
- 大龄技术人的出路在哪里?6月20日长沙-中国技术开放日邀请你一起探讨
- oracle中job无法正常运行,如何排查
- linux 内核编程 延时函数,linux中内核延时编程
- Scala的所有符号运算符都意味着什么?
- 电工产品的电磁兼容要求
- Docker 加速器
- 基础晶体管放大电路设计七步走
- 程序员的副业:我的第一本书出版啦!
- Lumion 11学会像真正的专业人士一样渲染
- win10查看无线密码
- 广州微创软件科技有限公司面试总结
- 付永刚计算机信息安全技术课后答案
- MicroKMS神龙版
- python编写word_如何使用Python来编辑word
- 专访架构师周爱民:谈企业软件架构设计 1
- 因素分析的基本原理对SPSS因素分析结果的解释
- 什么是资金主力的撤资?主力撤资方式有哪些?