[记录]2020CCPC网络赛
2020CCPC网络赛(部分题解)
在队友的帮助摸了4道比较简单的题,1002读懂题意知道了怎么做,无奈n太大无法处理素数(知识盲区,不会Min25筛),1005没有分辨出是nim博弈,还是太菜了~~。
持续更新中
1002 Graph Theory Class
待更新
题意:
思路:分段打表或min25筛
1003 Express Mail Taking
挺水的,不过感觉题目意思有点歧义(只需要去K号柜子一次即可),而且读错题意写出来的代码还能错样例就有点裂开。
题意:n个柜子排成一排,每个柜子之间间距为1,其中m个柜子存放快递,第k号柜子比较特殊,不存放快递,但是取其他柜子的快递需要来k号柜子输入密码打开相应的柜子(类似蜂巢的中控区)。从1号柜子出发,取完所有的快递后需要返回到1号柜子,求最短的距离。
思路:简单贪心。对于不同的走法,每次从k号柜子出发去相应柜子拿快递的距离都是固定的,那么最后总距离的区别就在于从最后一件快递所在的柜子返回到1号柜子。那么只需要最后一件快递离1号柜子最近即可,最后再加上从1前往k的区里即可。
#include<cstdio>
#include<cstring>
#include<cmath>
#include<iostream>
#include<iomanip>
#include<algorithm>
#include<string>
#include<set>
#include<stack>
#include<queue>
#include<map>
#include<vector>
#include<stdlib.h>
#include<time.h>
#include<fstream>
#define mmset(a, b) memset(a, b, sizeof(a))
#define FO(a, b, c) for(int a = b;a < c;a++)
#define FOR(a, b, c) for(int a = b;a <= c;a++)
#define ROF(a, b, c) for(int a = b;a >= c;a--)
#define vi vector<int>
using namespace std;
typedef long long ll;
void FIO()
{
// #ifndef ONLINE_JUDGE
// freopen("D:/Code/CC++/in.txt","r", stdin);
// freopen("D:/Code/CC++/out.out","w", stdout);
// #endif
ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
}
inline int read(){
int x = 0, f = 1;
char ch = getchar();
while(ch < '0' || ch > '9'){
if (ch == '-')
f = -1;
ch = getchar();
}
while(ch >= '0' && ch <= '9'){
x = (x<<1) + (x<<3) + (ch^48);
ch = getchar();
}
return x * f;
}
const int M = 1e6 + 10;
const int mod = 1e9 + 7;
const int inf = 0x3f3f3f3f;
const int dir[4][2]={1,0, 0,1, -1,0, 0,-1};//上、右、下、左四个方向
int a[M];
int main()
{
FIO();
int t, n, m, k;
cin >> t;
while(t--){
cin >> n >> m >> k;
FOR(i, 0, m-1)
cin >> a[i];
sort(a, a+m);
ll ans = k - 1;
ROF(i, m-1, 1){
ans += 2 * abs(k - a[i]);
}
ans += abs(k - a[0]) + a[0] - 1;
/*偷懒直接用了sort对柜子序号排序。可以不用排序的写法如下:
ll ans = 0;
int minn = inf; //记录离1最近的柜子
FOR(i, 0, m-1){
ans += 2 * abs(k - a[i]);
minn = min(minn, a[i]);
}
ans += 2 * (k - 1);
ans -= 2 * max(0, k - minn);
*/
cout << ans << endl;
}
//cout << setiosflags(ios::fixed) << setprecision(2) << ans << endl; //c++控制小数点位数
//system("pause");
return 0;
}
1005 Lunch
待更新
题意:
思路:nim博弈
1007 CCPC Training Class
有CF内味儿了,只要读懂了题就能解,害。
题意:对于一个字符串\(s = s_1s_2s_3\cdots s_n\),用\(s[l:r]\)表示从\(s_l\)到\(s_r\),当\(l>r\)时,\(s[l:r]\)为空。定义一个函数\(Lborder_i = max\{0 \le j < i|s[1:j] = s[i-j+1:i]\}\),定义\(D(s) = D(Lborder_i) + 1\),当s为空时,\(D(s) = 0\)。
给定一个字符串,可以对其进行重排,令\(W = \max_{i=0}^{n}D(i)\),求W。
思路:看似有点复杂,实际上只是求一个出现最多的字母次数。
#include<cstdio>
#include<cstring>
#include<cmath>
#include<iostream>
#include<iomanip>
#include<algorithm>
#include<string>
#include<set>
#include<stack>
#include<queue>
#include<map>
#include<vector>
#include<stdlib.h>
#include<time.h>
#include<fstream>
#define mmset(a, b) memset(a, b, sizeof(a))
#define FO(a, b, c) for(int a = b;a < c;a++)
#define FOR(a, b, c) for(int a = b;a <= c;a++)
#define ROF(a, b, c) for(int a = b;a >= c;a--)
#define vi vector<int>
using namespace std;
typedef long long ll;
void FIO()
{
// #ifndef ONLINE_JUDGE
// freopen("D:/Code/CC++/in.txt","r", stdin);
// freopen("D:/Code/CC++/out.out","w", stdout);
// #endif
ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
}
inline int read(){
int x = 0, f = 1;
char ch = getchar();
while(ch < '0' || ch > '9'){
if (ch == '-')
f = -1;
ch = getchar();
}
while(ch >= '0' && ch <= '9'){
x = (x<<1) + (x<<3) + (ch^48);
ch = getchar();
}
return x * f;
}
const int M = 1e5 + 10;
const int mod = 1e9 + 7;
const int inf = 0x3f3f3f3f;
const int dir[4][2]={1,0, 0,1, -1,0, 0,-1};//上、右、下、左四个方向
int a[30];
int main()
{
FIO();
string s;
int t, cnt = 1;
cin >> t;
while(t--){
cin >> s;
mmset(a, 0);
int maxn = 0;
FOR(i, 0, s.size()-1){
a[s[i] - 'a']++;
}
FOR(i, 0, 26)
maxn = max(maxn, a[i]);
cout << "Case #" << cnt++ << ": " << maxn << endl;
}
//cout << setiosflags(ios::fixed) << setprecision(2)
<< ans << endl; //c++控制小数点位数
//system("pause");
return 0;
}
1010 Reports
签到题
题意:给定一个长度为n的01串,判断是否有连续的0或1出现,有则输出"NO",否则输出"YES"
#include<cstdio>
#include<cstring>
#include<cmath>
#include<iostream>
#include<iomanip>
#include<algorithm>
#include<string>
#include<set>
#include<stack>
#include<queue>
#include<map>
#include<vector>
#include<stdlib.h>
#include<time.h>
#include<fstream>
#define mmset(a, b) memset(a, b, sizeof(a))
#define FO(a, b, c) for(int a = b;a < c;a++)
#define FOR(a, b, c) for(int a = b;a <= c;a++)
#define ROF(a, b, c) for(int a = b;a >= c;a--)
#define vi vector<int>
using namespace std;
typedef long long ll;
void FIO()
{
// #ifndef ONLINE_JUDGE
// freopen("D:/Code/CC++/in.txt","r", stdin);
// freopen("D:/Code/CC++/out.out","w", stdout);
// #endif
ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
}
inline int read(){
int x = 0, f = 1;
char ch = getchar();
while(ch < '0' || ch > '9'){
if (ch == '-')
f = -1;
ch = getchar();
}
while(ch >= '0' && ch <= '9'){
x = (x<<1) + (x<<3) + (ch^48);
ch = getchar();
}
return x * f;
}
const int M = 1e5 + 10;
const int mod = 1e9 + 7;
const int inf = 0x3f3f3f3f;
const int dir[4][2]={1,0, 0,1, -1,0, 0,-1};//上、右、下、左四个方向
int a[55];
int main()
{
FIO();
int n, t;
cin >> t;
while(t--){
cin >> n;
bool flag = 0;
FOR(i, 0, n-1){
cin >> a[i];
}
FOR(i, 1, n-1){
if(a[i] == a[i-1]){
flag = 1;
break;
}
}
if(flag)
cout << "NO" << endl;
else
cout << "YES" << endl;
}
//cout << setiosflags(ios::fixed) << setprecision(2) << ans << endl; //c++控制小数点位数
//system("pause");
return 0;
}
1011 3x3 Convolution
在大佬的帮助下解出了这道题。不过有点搞人,题目没有说明要处理行末空格,PE白给了一次。
题意:给定一个\(n*n\)的矩阵A和一个\(3*3\)的矩阵K,矩阵K是一个小数矩阵并且所有元素之和等于1。定义一个函数C(A, K),对于函数函数C(A, K)里的值也是构成一个\(n*n\)的矩阵,其中每一元素为\(C_{x,y} = {\sum_{i=1}^{min(n-x+1,3)}\sum_{j=1}^{min(n-y+1,3)}A_{x+i-1,y+j-1}K_{i,j}}\)。定义\(C^m(A, K) = C(C^{m-1}(A, K), K), C^1(A, K) = C(A, K)\),求\(\lim\limits_{t \rightarrow \infty}C^t(A, K)\)。其中K矩阵会用整数矩阵K'代替,矩阵K和K'的对应关系为:\(K_{i, j} = K'_{i, j} / (\sum_{x = 1}^{3}\sum_{y=1}^{3}K'_{x,y})\)
思路:K是一个小数矩阵,A是一个整数矩阵,并且答案是一个整数矩阵,那么最后求的矩阵的\(C_{1,1}\)一定是整数。简单证明一下,假设A是一个4*4的矩阵,那么\(C_{1,1} = {\sum_{i=1}^{3}\sum_{j=1}^{3}A_{i,j}K_{i,j}}\),画图表示就是:

\(C_{1,1}\)就是矩阵A×矩阵K。
因为要求\(\lim\limits_{t \rightarrow \infty}C^t(A, K)\),就是说矩阵A×矩阵K乘了无数次,那么要让最后求的矩阵的\(C_{1,1}\)是整数,那么\(K_{1,1}\)必定是一个整数。因此只需要判断矩阵K'中大于0的数有多少个,超过1那么就输出\(n*n\)的0矩阵,等于1则输出矩阵A。
#include<cstdio>
#include<cstring>
#include<cmath>
#include<iostream>
#include<iomanip>
#include<algorithm>
#include<string>
#include<set>
#include<stack>
#include<queue>
#include<map>
#include<vector>
#include<stdlib.h>
#include<time.h>
#include<fstream>
#define mmset(a, b) memset(a, b, sizeof(a))
#define FO(a, b, c) for(int a = b;a < c;a++)
#define FOR(a, b, c) for(int a = b;a <= c;a++)
#define ROF(a, b, c) for(int a = b;a >= c;a--)
#define vi vector<int>
using namespace std;
typedef long long ll;
void FIO()
{
// #ifndef ONLINE_JUDGE
// freopen("D:/Code/CC++/in.txt","r", stdin);
// freopen("D:/Code/CC++/out.out","w", stdout);
// #endif
ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
}
inline int read(){
int x = 0, f = 1;
char ch = getchar();
while(ch < '0' || ch > '9'){
if (ch == '-')
f = -1;
ch = getchar();
}
while(ch >= '0' && ch <= '9'){
x = (x<<1) + (x<<3) + (ch^48);
ch = getchar();
}
return x * f;
}
const int M = 1e2 + 10;
const int mod = 1e9 + 7;
const int inf = 0x3f3f3f3f;
const int dir[4][2]={1,0, 0,1, -1,0, 0,-1};//上、右、下、左四个方向
int a[M][M];
int b[5][5];
int main()
{
//FIO();
int t, n;
cin >> t;
while(t--){
int cnt = 0;
cin >> n;
FOR(i, 0, n-1)
FOR(j, 0, n-1)
cin >> a[i][j];
FOR(i, 0, 2){
FOR(j, 0, 2){
cin >> b[i][j];
if(b[i][j])
cnt++;
}
}
FOR(i, 0, n-1){
FOR(j, 0, n-1){
if(cnt > 1)
printf(j == 0?"0":" 0");
else
printf(j == 0?"%d":" %d", a[i][j]);
}
printf("\n");
}
}
//cout << setiosflags(ios::fixed) << setprecision(2) << ans << endl; //c++控制小数点位数
//system("pause");
return 0;
}

浙公网安备 33010602011771号