ACM团队周赛题解(2)

拉了CF583和CF486的两套div2题目

还是先贴宏定义部分

#define MAXN 1000000+5
#define MOD 1000000007
#define PI (acos(-1.0))
#define EPS 1e-6
#define MMT(s,a) memset(s, a, sizeof s)
#define GO(i,a,b) for(int i = (a); i < (b); ++i)
#define GOE(i,a,b) for(int i = (a); i <= (b); ++i)
#define OG(i,a,b) for(int i = (a); i > (b); --i)
#define OGE(i,a,b) for(int i = (a); i >= (b); --i)


A - Asphalting Roads(CF-583A)

题意就是n条水平路,n条竖直路,构成井字形状。然后第i天会到(xi,yi)这个路口,如果这个路口得两条路都没有被染色,就输出这天并把两个路口都染上颜色,否则跳到下一天。

输出所有可以染色得天数。

题目思路:标记遍历即可

 1 int main(){
 2     ios_base::sync_with_stdio(false), cout.tie(0), cin.tie(0);
 3     int n,x,y;
 4     cin>>n;
 5     int mp1[55] = {0},mp2[55] = {0};
 6     GO(i,0,n*n){
 7         cin>>x>>y;
 8         if(mp1[x] == 0 && mp2[y] == 0){
 9             cout << i+1 << " ";
10             mp1[x] = mp2[y] = 1;
11         }
12     }
13     cout << endl;
14
15     return 0;
16 }

B - Robot‘s Task(CF-583B)

题意就是最开始从左往右走,如果现在值Num比a[i]大,则Num+1,否则跳过他,走到尽头如果有数没有经过,则转向再次走,已经走过的地方不能再走。

Num初始值为0,问至少转向几次。

思路:模拟即可

 1 int main(){
 2     ios_base::sync_with_stdio(false), cout.tie(0), cin.tie(0);
 3     int n;
 4     int a[1005] = {0},vis[1005] = {0};
 5     cin>>n;
 6     GOE(i,1,n){
 7         cin>>a[i];
 8     }
 9     bool flag = true;
10     int cnt = n,ans = 0,num = 0;
11     while(cnt > 0){
12         if(flag){
13             GOE(i,1,n){
14                 if(!vis[i] && num >= a[i]){
15                     vis[i] = 1;
16                     num++;
17                     cnt--;
18                 }
19             }
20         }
21         else{
22             OGE(i,n,1){
23                 if(!vis[i] && num >= a[i]){
24                     vis[i] = 1;
25                     num++;
26                     cnt--;
27                 }
28             }
29         }
30         flag = !flag;
31         if(cnt > 0)
32             ans++;
33     }
34     cout << ans << endl;
35
36     return 0;
37 }

C - GCD Table(CF-583C)

给你一个打乱了的GCD表,问是哪些值构成的。

思路:这n个数一定就是对角线上的数,直接降序排列然后暴力找,每次找到的最大的数一定是其中一个数,然后求出它与已经求出的所有数的gcd在队列中去掉两个这个gcd数,保证所有大于等于下一个数字的gcd一定都被去掉了,剩下的最大的又是要找的数。

额外定义

template<typename T>
using maxHeap = priority_queue<T, vector<T>, less<T> >;

template<typename T>
inline T gcd(T a, T b){ return b==0 ? a : gcd(b,a%b); }

代码

 1 int main(){
 2     ios_base::sync_with_stdio(false), cout.tie(0), cin.tie(0);
 3     int n,k = 0,temp,num;
 4     int a[250050],b[250050];
 5     cin>>n;
 6     GOE(i,1,n*n){
 7         cin>>a[i];
 8     }
 9     sort(a+1,a+1+n*n);
10     maxHeap<int> q;
11     OG(i,n*n,0){
12         if(!q.empty())
13             temp = q.top();
14         else
15             temp = 0;
16         if(a[i] == temp){
17             q.pop();
18             continue;
19         }
20         GO(j,0,k){
21             num = gcd(b[j],a[i]);
22             q.push(num);
23             q.push(num);
24         }
25         b[k++] = a[i];
26     }
27     GO(i,0,k)
28         cout << b[i] << " ";
29     cout << endl;
30
31     return 0;
32 }

F - Calculating Function(CF-486A)

题意就是按照他给的公式输出F(n);

思路:可以推出n为偶数是F(n) = n/2,否则F(n) = n/2 - n;

代码

 1 int main(){
 2     ios_base::sync_with_stdio(false), cout.tie(0), cin.tie(0);
 3     ll n;
 4     cin>>n;
 5     if (n&1)
 6         cout << n/2 - n << endl;
 7     else
 8         cout << n/2 << endl;
 9
10     return 0;
11 }

G - OR in Matrix(CF-486B)

题目就是说bij为i行和j列的值OR操作的结果,现在给你操作后的表,要你求操作前的表。

思路:如果bij = 0,则证明i行和j列全是0,如果是1,则证明i行和j列必须有一个1,所以先把所有值设为1,按照题目把某些行列变为0,再判断一遍是否满足题意即可

代码

 1 int main(){
 2     ios_base::sync_with_stdio(false), cout.tie(0), cin.tie(0);
 3     int n,m;
 4     int a[105][105],b[105][105];
 5     fill(b[0],b[0]+105*105,1);
 6     cin>>n>>m;
 7     GOE(i,1,n){
 8         GOE(j,1,m){
 9             cin>>a[i][j];
10             if(a[i][j] == 0){
11                 GOE(ii,1,n)
12                     b[ii][j] = 0;
13                 GOE(jj,1,m)
14                     b[i][jj] = 0;
15             }
16         }
17     }
18
19     GOE(i,1,n){
20         GOE(j,1,m){
21             if(a[i][j] == 1){
22                 int flag = 0;
23                 GOE(ii,1,n){
24                     if(b[ii][j] == 1){
25                         flag = 1;
26                         break;
27                     }
28                 }
29                 GOE(jj,1,m){
30                     if(b[i][jj] == 1){
31                         flag = 1;
32                         break;
33                     }
34                 }
35                 if(!flag){
36                     cout << "NO" << endl;
37                     exit(0);
38                 }
39             }
40         }
41     }
42
43     cout << "YES" << endl;
44     GOE(i,1,n){
45         GOE(j,1,m)
46             cout << b[i][j] << " ";
47         cout << endl;
48     }
49
50     return 0;
51 }

H - Palindrome Transformation(CF-486C)

题意就是4种操作,最开始在k位置操作,问最少操作多少次使得原串变成回文串。

思路:因为是对称的,我们先不要管最开始在哪个位置,遍历即可,当a[i] != a[n-i-1]时候,我们再想是变a[i]还是变另一个,然后答案加上这个值。同时往容器中加上从k走到i远还是走到n-i-1近。

最后排序,答案加上最远距离于最近距离之差再加上这两者距离k最近的距离即可。

为什么只需要不需要管k的位置,因为k无论在哪里,我们都需要把所有不符合的字符走到,所以这里得花掉最远距离和最近距离的差,同时我们最开始在k,需要走到最近的位置开始遍历上一段距离,所以最终答案就是

  ans = 每个不合格字符的操作次数 + 不合格字符的区间长度 + 从k位置走到这个区间的某一端点的距离;

因为不管你的k是否在这个区间内,都需要遍历一遍这个区间。

 1 int main(){
 2     ios_base::sync_with_stdio(false), cout.tie(0), cin.tie(0);
 3     int n,k;
 4     string s;
 5     vector<int> q;
 6     cin>>n>>k>>s;
 7     int len = n/2,ans = 0;
 8     GO(i,0,len){
 9         if(s[i] != s[n-1-i]){
10             int tp = abs(s[i] - s[n-1-i]);
11             tp = min(tp,26-tp);
12             ans += tp;
13             if(tp)
14                 q.PB((abs(i+1-k) < abs(n-i-k)) ? i+1 : n-i);
15         }
16     }
17     int cnt = q.size();
18     if(q.empty())
19         cout << ans << endl;
20     else{
21         sort(q.begin(),q.end());
22         ans += q[cnt-1] - q[0] + min(abs(q[cnt-1]-k),abs(q[0]-k));
23         cout << ans << endl;
24     }
25     return 0;
26 }


D题E题时间关系暂时不补了。

原文地址:https://www.cnblogs.com/xenny/p/9689670.html

时间: 2024-08-04 01:03:39

ACM团队周赛题解(2)的相关文章

ACM团队周赛题解(3)

940和822两套div.2 老规矩 #define MAXN 1000000+5#define MOD 1000000007#define PI (acos(-1.0))#define EPS 1e-6#define MMT(s,a) memset(s, a, sizeof s)#define GO(i,a,b) for(int i = (a); i < (b); ++i)#define GOE(i,a,b) for(int i = (a); i <= (b); ++i)#define OG

2016 年宁波工程学院第七届ACM校赛题解报告

2016 年宁波工程学院第七届ACM校赛题解报告 本题解代码直接为比赛代码,仅供参考. A,B,C,D,G,H,J,K,L,M 来自 Ticsmtc 同学. F 来自 Gealo 同学. E,I 来自Alex 学长. Promblem A :    Two Sum 时间限制: 1 Sec  内存限制: 64 MB 题目描述: 给出n个数,另外给出?个整数S,判断是否可以从中取出2个数,使得这两个数的和是S. 输入: 第?行有个整数T(1 <= T <= 10),代表数据组数. 对于每组数据,第

Leetcode 第174场周赛 题解

Leetcode 第174场周赛 题解 方阵中战斗力最弱的 K 行 签到题,统计一下每行的军人数量,然后设置一下排序规则即可. 时间复杂度 \(O(nlogn)\) typedef long long ll; typedef double db; #define _for(i,a,b) for(int i = (a);i < b;i ++) #define _rep(i,a,b) for(int i = (a);i > b;i --) #define INF 0x3f3f3f3f3f3f3f3

Leetcode 第175场周赛 题解(完结)

Leetcode 第175场周赛 题解 检查整数及其两倍数是否存在 数据范围小的可怜,\(O(n^2)\) 解法可行.如果范围大一点,可以先进行排序然后遍历每一个数进行二分查找,时间复杂度 \(O(nlogn)\) 代码是平方解法. typedef long long ll; typedef double db; #define _for(i,a,b) for(int i = (a);i < b;i ++) #define _rep(i,a,b) for(int i = (a);i > b;i

ACM团队招新赛题解

标程代码全部为C语言编写.代码中的#if LOCAL_ 至#endif为本地一些调试内容,可以忽略. Xenny的A+B(1)[容易][签到] 签到题,做不出的话可能你有点不太适合ACM了. Xenny的A+B(2)[容易][签到] 也没什么好说的,用一个循环控制输入的次数就行了 Xenny的A+B(3)[困难][模拟] 这是本次比赛最难的题目,用意在于赛后你们看见此题题解可以开拓一下思维方式,不要局限于中学的思维,要掌握计算机. 乍一看这题没法做,怎么去存A和B两个这么大的数字,但我们可以用数

第三次周赛题解【并查集 KMP DFS BFS 快速幂】

问题 A: 一道签到题 时间限制: 2 Sec  内存限制: 128 MB 提交: 63  解决: 28 [提交][状态][讨论版] 题目描述 我想说这是一道签到题,意思就是本次测试中最水的一道,不过我这样说你真的愿意相信我吗?哈哈,题目是这样的给你一下小数,然后请告诉我分别告诉我这个小数的循环节的循环次数.循环节以及循环节长度 输入 输入包括多组测试数据每组测试数据1行,包括一个小数,小数的长度不超过200,小数大于0小于100 输出 分别输出这个小数的循环节的长度.循环节以及循环次数,中间以

河南省第三届ACM程序设计大赛题解

光说不练是假把式,先给各大巨巨们一个刷题链接:戳我进入刷题OJ 这届比赛水题有点多,想拿奖保证好手速即可.但是想拿高名次并不太容易 A.常规做法我不太会,但是根据题目的数据发现,可以开个这么大的数组哈哈,那么万能的暴力保证1A. #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int maxn=500; int num[maxn]; int main(){

Leetcode 184周赛题解

前一宿没睡好,困的不行,写的有点慢.. 5380. 数组中的字符串匹配 题目描述: 给你一个字符串数组 words ,数组中的每个字符串都可以看作是一个单词.请你按 任意 顺序返回 words 中是其他单词的子字符串的所有单词.如果你可以删除 words[j] 最左侧和/或最右侧的若干字符得到 word[i] ,那么字符串 words[i] 就是 words[j] 的一个子字符串. 题解: 两次遍历,用kmp判断一下是否是字串. AC代码: class Solution { public: in

第十周周赛题解

A题: 二分题目,具体二分公式看我代码吧(ーー゛) 1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 #include<cstring> 5 #define maxa 20100 6 using namespace std; 7 int a[maxa],l[maxa],r[maxa],n; 8 bool comp(int p) 9 { 10 int x= a[1],y= p-a[1