Codeforces 1072 - A/B/C/D - (Done)
链接:http://codeforces.com/contest/1072/
A - Golden Plate - [计算题]
- #include<bits/stdc++.h>
- using namespace std;
- inline int calc(int w,int h){return (w+h-)*;}
- int w,h,k;
- int ans;
- int main()
- {
- cin>>w>>h>>k;
- for(;w&&h&&k;w-=,h-=,k--) ans+=calc(w,h);
- cout<<ans<<endl;
- }
B - Curiosity Has No Limits - [DFS]
对于常数 $C_1,C_2$ 和变量 $x,y$ 的方程组:
$\left\{ {\begin{array}{*{20}c} {C_1 = x|y} \\ {C_2 = x\& y} \\ \end{array}} \right.$
除了 $x$ 和 $y$ 之间能互换一下之外,其实解是唯一的。
因此,说是从 $1$ 到 $n$ 的深搜,其实只是 $O(n)$ 的枚举,因为当你确定了第一个数字 $t[1]$ 之后,后面的跟着都是确定的,因此只会DFS只会跑一条深度为 $n$ 的链。
- #include<bits/stdc++.h>
- using namespace std;
- typedef pair<int,int> pii;
- const int maxn=1e5+;
- int n;
- pii a[maxn],b[maxn];
- pii cho[];
- bool judge(pii a,pii b,pii x,pii y)
- {
- if((x.first|y.first)!=a.first || (x.second|y.second)!=a.second) return ;
- if((x.first&y.first)!=b.first || (x.second&y.second)!=b.second) return ;
- return ;
- }
- bool ok;
- int c[maxn];
- void dfs(int d,int p)
- {
- if(ok) return;
- if(d==n+)
- {
- ok=;
- return;
- }
- for(int i=;i<=;i++)
- {
- if(judge(a[d-],b[d-],cho[p],cho[i]))
- {
- c[d]=i;
- dfs(d+,i);
- }
- }
- }
- int main()
- {
- cho[]=make_pair(,);
- cho[]=make_pair(,);
- cho[]=make_pair(,);
- cho[]=make_pair(,);
- cin>>n;
- for(int i=,k;i<n;i++)
- {
- scanf("%d",&k);
- a[i].first=k/;
- a[i].second=k%;
- }
- for(int i=,k;i<n;i++)
- {
- scanf("%d",&k);
- b[i].first=k/;
- b[i].second=k%;
- }
- ok=;
- for(int i=;i<=;i++)
- {
- c[]=i;
- dfs(,i);
- if(ok) break;
- }
- if(ok)
- {
- printf("YES\n");
- for(int i=;i<=n;i++) printf("%d ",c[i]);
- printf("\n");
- }
- else printf("NO\n");
- }
C - Cram Time - [暴力]
(忍不住想说,我队友太强了,跟他组队是我拖后腿了55555)
显然,要放最多的数进去,肯定是放 $1 \sim n$,其中 $n$ 是满足 $\frac{{\left( {n + 1} \right)n}}{2} \le a + b$ 的最大整数。
考虑第一天看 $a$ 的书,我们从最大的 $n$ 枚举起,遇到能塞得下的就往里塞,这样必然可以让第一天的 $a$ 个小时被占满,
而剩下的全部放到第二天就行了,剩下的那些加起来必然不会超过 $b$ 小时。
- #include<bits/stdc++.h>
- using namespace std;
- typedef long long ll;
- const int maxn=;
- ll a,b;
- ll n;
- bool vis[maxn];
- int main()
- {
- cin>>a>>b;
- for(n=;n<maxn;n++) if((n+)*n/<=a+b && (n+)*(n+)/>a+b) break;
- memset(vis,,sizeof(vis));
- int cnt=;
- for(int i=n;i>=;i--)
- {
- if(a>=i)
- {
- vis[i]=;
- a-=i;
- cnt++;
- }
- }
- printf("%d\n",cnt);
- for(int i=;i<=n;i++) if(vis[i]) printf("%d ",i);
- printf("\n");
- printf("%d\n",n-cnt);
- for(int i=;i<=n;i++) if(!vis[i]) printf("%d ",i);
- printf("\n");
- }
D - Minimum path - [BFS]
题意:
给出存储小写字母的 $n \times n$ 的矩阵,规定每次只能往下跑一格或者往右跑一个,要从左上角的 $(1,1)$ 跑到右下角 $(n,n)$,问路径上产生的字符串字典序最小是哪个(另外, 你有 $k$ 次机会能够修改某个字母为任意一个字母)。
题解:
按照反对角线,从第 $1$ 层的 $(1,1)$ 跑到第 $2 \times n - 1$ 层的 $(n,n)$,构建两个队列(数组模拟)q[0] 和 q[1],
队列里面存储一个Node结构体,Node结构体中存储:目前我走到的了 $(i,j)$,给相应路径上产生字符 $c$,接下来我还有多少次 $k$ 能用。
1、从当前层往下一层BFS,从当前 q[f] 队列(其中 f = 0 or 1)取出节点,最多有 $O(n)$ 个节点。
2、通过这个节点计算出它下一层可能会走到的节点,入队 q[f^1]。
3、同时,在入队时,我们要把所有能去重的全都去重(就是当前层的两格 $(i+1,j)$ 和 $(i,j+1)$ 都走到下一层的 $(i+1,j+1)$,这种情况只需要判断一下哪个更优即可,显然是字符越小的越优,如果字符相同,那么肯定是 $k$ 越大越优);
4、另外,我们用 $mini$ 变量记录 q[f^1] 队列中所有元素里字典序最小的字符(这个字符就是要求输出的字符串中第 $k$ 个位置上的字符),而对于 q[f^1] 中大于 $mini$ 的字符的元素,统统都可以去掉(用vis数组标记掉),如果处理完发现 q[f^1] 队列已经空了,就跳出BFS;否则就清空 q[f] 队列,然后令 f^=1,回到步骤 1 继续。
时间复杂度:
BFS一共前进 $O(n)$ 层,每层要遍历一遍当前队列取出当前节点,而队列中元素不超过 $O(n)$,同时产生的下个队列内元素一样不会超过 $O(n)$,因此时间复杂度为 $O(n^2)$。
AC代码:
- #include<bits/stdc++.h>
- using namespace std;
- const int maxn=;
- int n,k;
- char mp[maxn][maxn];
- vector<char> ans;
- struct Node{
- char c;
- int i,j;
- int k;
- Node(){}
- Node(char _c,int _i,int _j,int _k){c=_c,i=_i,j=_j,k=_k;}
- bool operator<(const Node& oth)const
- {
- if(c==oth.c) return k>oth.k;
- else return c<oth.c;
- }
- };
- int tot[];
- Node q[][*maxn];
- int vis[maxn][maxn];
- const int dx[]={,},dy[]={,};
- inline bool in(int i,int j){return (<=i && i<=n && <=j && j<=n);}
- void bfs()
- {
- tot[]=;
- tot[]=;
- memset(vis,-,sizeof(vis));
- if(mp[][]=='a') q[][tot[]++]=Node('a',,,k);
- else q[][tot[]++]=Node(k?'a':mp[][],,,max(,k-));
- ans.push_back(q[][].c);
- vis[][]=;
- int f=;
- Node now,nxt;
- while(tot[f])
- {
- int mini=(int)('z'+);
- for(int i=;i<tot[f];i++)
- {
- now=q[f][i];
- if(vis[now.i][now.j]==-) continue;
- for(int z=;z<=;z++)
- {
- int x=now.i+dx[z], y=now.j+dy[z];
- if(!in(x,y)) continue;
- if(mp[x][y]=='a') nxt=Node('a',x,y,now.k);
- else nxt=Node(now.k?'a':mp[x][y],x,y,max(,now.k-));
- if(vis[x][y]==-)
- {
- vis[x][y]=tot[f^];
- q[f^][tot[f^]++]=nxt;
- mini=min(mini,(int)nxt.c);
- }
- else
- {
- Node &tmp=q[f^][(vis[x][y])];
- if(nxt<tmp) tmp=nxt, mini=min(mini,(int)nxt.c);
- }
- }
- }
- if(mini<(int)('z'+)) ans.push_back((char)mini);
- else break;
- for(int i=;i<tot[f^];i++)
- {
- nxt=q[f^][i];
- if((int)nxt.c>mini) vis[nxt.i][nxt.j]=-;
- }
- tot[f]=;
- f^=;
- }
- }
- int main()
- {
- cin>>n>>k;
- for(int i=;i<=n;i++) scanf("%s",mp[i]+);
- if(k+>=n+n)
- {
- for(int i=;i<=*n-;i++) printf("a");
- printf("\n");
- return ;
- }
- ans.clear();
- bfs();
- for(int i=;i<ans.size();i++) printf("%c",ans[i]);
- printf("\n");
- }
Codeforces 1072 - A/B/C/D - (Done)的更多相关文章
- Codeforces 1072 C - Cram Time
C - Cram Time 思路:首先找到最大的x,使得x*(x+1)/2 <= a+b 那么一定存在一种分割使得 a1 <= a 且 b1 <= b 证明: 从x 到 1枚举过去, ...
- Codeforces Round #517 (Div. 2, based on Technocup 2019 Elimination Round 2) D. Minimum path
http://codeforces.com/contest/1072/problem/D bfs 走1步的最佳状态 -> 走2步的最佳状态 -> …… #include <bits/ ...
- Codeforces Round #517 (Div. 2, based on Technocup 2019 Elimination Round 2) D. Minimum path(字典序)
https://codeforces.com/contest/1072/problem/D 题意 给你一个n*n充满小写字母的矩阵,你可以更改任意k个格子的字符,然后输出字典序最小的从[1,1]到[n ...
- codeforces #516---ABC
A---golden plate http://codeforces.com/contest/1072/problem/A 题意:给一个n*m的格子,从最外层往里涂色,每次尽量涂最外面的那一圈,两圈涂 ...
- Codeforces 517 #B
http://codeforces.com/contest/1072/problem/B 开始想的只有搜索,时间复杂度$O(4^n)$,明显有问题. 想了半个小时没有思路,然后想到了正难则反,就开始步 ...
- Codeforces 517 #A
http://codeforces.com/contest/1072/problem/A 题目挺简单,就是让你求几个环,占得方格的个数,然而题目为什么给出了公式呢? 然而给出的公式辣么丑,还是不用的好 ...
- Codeforces Round #517 (Div. 2)(1~n的分配)
题:https://codeforces.com/contest/1072/problem/C 思路:首先找到最大的x,使得x*(x+1)/2 <= a+b 那么一定存在一种分割使得 a1 &l ...
- Codeforces 1408I - Bitwise Magic(找性质+集合幂级数)
Codeforces 题面传送门 & 洛谷题面传送门 Yet another immortal D1+D2 I %%%%%% 首先直接统计肯定是非常不容易的,不过注意到这个 \(k\) 非常小 ...
- python爬虫学习(5) —— 扒一下codeforces题面
上一次我们拿学校的URP做了个小小的demo.... 其实我们还可以把每个学生的证件照爬下来做成一个证件照校花校草评比 另外也可以写一个物理实验自动选课... 但是出于多种原因,,还是绕开这些敏感话题 ...
随机推荐
- 每天一个linux命令:chgrp
1.命令简介 chgrp(Change group) 用来将每个指定文件的所属组设置为指定值.如果使用 --reference,则将每个文件的所属组设置为与指定参考文件相同. 2.用法 ...
- TRAC-IK机器人运动学求解器
TRAC-IK和Orocos KDL类似,也是一种基于数值解的机器人运动学求解器,但是在算法层面上进行了很多改进(Specifically, KDL’s convergence algorithms ...
- iOS如何在应用中添加图标更换功能
一.在info.plist中设置图标信息 首先将需要更换的图标按照下面的方式声明,以便我们能够正常调用文件和方法.注意,每个图标的图标名称和对应的文件名要一一对应. 二.在工程根目录下添加图标文件 图 ...
- PHP访问SQL Server驱动对应关系
引用地址: https://docs.microsoft.com/en-us/sql/connect/php/system-requirements-for-the-php-sql-driver?vi ...
- 【C++】C++中的迭代器
目录结构: contents structure [-] 迭代器运算符 迭代器类型 begin和end运算符 迭代器的算术运算 可以使用下标来访问string对象或vector对象的元素,还有另外一种 ...
- [k8s]k8s的控制层kubelet+docker配合调度机制(k8架构)
意外停掉一台node的kubelet,发现调度有问题,研究了下调度的细节 k8s架构 控制层- kubelet(配合节点docker工作) 数据层- kube-proxy 逻辑图: object 参考 ...
- IOS-企业开发人员账号&邓白氏码申请记录
Apple开发人员账号分三种,个人.公司,还有企业.个人和公司都称为标准账号. 另一种是教育机构的账号. 账号介绍 个人和公司的就不说了.如今仅仅说企业账号 首先是申请企业账号的地址: https:/ ...
- vux安装中遇到的坑(转)
1.输入 npm install vux --save 2.输入 npm install vux-loader --save-dev(没安装的时候,会一直报错) 3.build/webpack.bas ...
- hbase region still in transition
1,删除hbase中的 hbase:meta表中相应的region的row 如; get 'hbase:meta','kylin_metadata,,1481101316881.f3b4c7c1148 ...
- sklearn中的模型评估-构建评估函数
1.介绍 有三种不同的方法来评估一个模型的预测质量: estimator的score方法:sklearn中的estimator都具有一个score方法,它提供了一个缺省的评估法则来解决问题. Scor ...