Gym-101653:acific Northwest Regional Contest (2019训练第一场)
本套题没有什么数据结构题,图论题,唯一有价值的就是Q题博弈,在最后面,读者可以直接拉到最下面。
(还剩下两个,估计每什么价值的题,懒得补了
M .Polyhedra
pro:欧拉公式,V-E+F=2;给定V,E,求F
sol:F=E-V+2;
- #include<bits/stdc++.h>
- #define rep(i,a,b) for(int i=a;i<=b;i++)
- using namespace std;
- const int maxn=;
- int main()
- {
- int T;
- scanf("%d", &T);
- while(T--)
- {
- int a, b;
- scanf("%d%d", &a, &b);
- printf("%d\n", b - a + );
- }
- return ;
- }
N .Majority
pro: 给定一些一些1到1000的数字,问最小的出现次数最多的数字。
sol: 模拟。
- #include<bits/stdc++.h>
- #define rep(i,a,b) for(int i=a;i<=b;i++)
- using namespace std;
- const int maxn=;
- int num[maxn];
- int main()
- {
- int T,N,x;
- scanf("%d",&T);
- while(T--){
- scanf("%d",&N);
- rep(i,,) num[i]=;
- rep(i,,N){
- scanf("%d",&x);
- num[x]++;
- }
- int ans=,x=-;
- rep(i,,) {
- if(num[i]>x) ans=i,x=num[i];
- }
- printf("%d\n",ans);
- }
- return ;
- }
O .Diamonds
pro:给定一些二元组,求最长的序列,满足a递增,b递减。
sol:N^2暴力即可。
- #include<bits/stdc++.h>
- #define rep(i,a,b) for(int i=a;i<=b;i++)
- using namespace std;
- const int maxn=;
- struct in{
- double x,y;
- }s[maxn];
- int dp[];
- int main()
- {
- int T,N,ans;
- scanf("%d",&T);
- while(T--){
- scanf("%d",&N); ans=;
- rep(i,,N) scanf("%lf%lf",&s[i].x,&s[i].y);
- rep(i,,N){
- dp[i]=;
- rep(j,,i-){
- if(s[j].x<s[i].x&&s[j].y>s[i].y) dp[i]=max(dp[i],dp[j]+);
- }
- ans=max(ans,dp[i]);
- }
- printf("%d\n",ans);
- }
- return ;
- }
R .Ramp Number
pro:一个数字X是合法的,当且仅当各位数字从左到右不降。 如果一个数字的合法,求多少个小于他的数是合法的。
sol:基本数位DP。
- #include<bits/stdc++.h>
- #define ll long long
- #define rep(i,a,b) for(int i=a;i<=b;i++)
- using namespace std;
- const int maxn=;
- ll dp[maxn][]; char c[maxn]; int a[maxn],len;
- ll dfs(int pos,int lim,int now)
- {
- if(pos==len) return ;
- if(!lim&&dp[pos][now]) return dp[pos][now];
- ll res=; int up=; if(lim) up=a[pos+];
- rep(j,now,up) res+=dfs(pos+,lim&&j==a[pos+],j);
- return dp[pos][now]=res;
- }
- void solve()
- {
- ll res=;
- rep(i,,len){
- memset(dp,,sizeof(dp));
- int up=; if(i==) up=a[];
- rep(j,,up) res+=dfs(i,i==&&j==up,j);
- }
- printf("%lld\n",res);
- }
- int main()
- {
- int T;
- scanf("%d",&T);
- while(T--){
- scanf("%s",c+);
- len=strlen(c+);
- rep(i,,len) a[i]=c[i]-'';
- bool F=true;
- rep(i,,len) if(a[i]<a[i-]) F=false;
- if(!F){ puts("-1"); continue;}
- solve();
- }
- return ;
- }
X .Wrench
pro:把一个带小数的数字表示为整数 加一个 分数形式,满足分母是2的幂次,而且要越小的满足的,允许有最后一位的误差。
sol:模拟,细节需要注意。
- #include<bits/stdc++.h>
- using namespace std;
- int t,n;
- char s[],s1[];
- int main(){
- for(scanf("%d",&t);t--;){
- scanf("%s",s);n=strlen(s);
- int p=;bool flag=,flag1=;
- while(s[p]==''&&p<n)p++;
- while(s[p]!='.'&&p<n)putchar(s[p++]),flag1=;
- for(int i=p+;i<n;i++)
- if(s[i]!=''){flag=;break;}
- if(flag){if(flag1)putchar(' ');}
- else{puts("\"");continue;}
- flag=;
- for(int i=;i<=;i<<=){
- for(int j=;j<i;j++){
- double x=1.0*j/i;
- for(int v=;v<;v++)x*=,s1[v]=(int)x%+'';
- bool f=;
- for(int k=;p+k<n;k++)
- if(s1[k-]!=s[p+k]&&(p+k<n-||s1[k-]+!=s[p+k])){f=;break;}
- if(f){printf("%d/%d\"\n",j,i);flag=;break;}
- }
- if(flag)break;
- }
- }
- return ;
- }
U .Top 25
题意:给定A和B,分别是不同的1到N的排列,找到连续的段(越短越好),代表的集合相同。
思路:每次找到对应的位置,如果最远的对应位置和当前相同,说明这段集合相同。
Map+clear: 3525ms
- #include<bits/stdc++.h>
- #define rep(i,a,b) for(int i=a;i<=b;i++)
- using namespace std;
- const int maxn=;
- map<string, int>Map;
- int f[maxn];
- vector<int>ans;
- int main()
- {
- int T;
- scanf("%d", &T);
- while(T--)
- {
- int N,x,y;
- Map.clear();
- string s;
- scanf("%d",&N);
- rep(i,,N){
- cin>>s;
- Map[s]=i;
- }
- rep(i,,N){
- cin >> s;
- f[Map[s]] = i;
- }
- rep(i,,N){
- if(i==f[i]) printf("1 ");
- else{
- int maxx = f[i];
- for(int j = i + ; j <= maxx; j++){
- if(f[j] > maxx)maxx = f[j];
- }
- printf("%d ",maxx-i+);
- i = maxx;
- }
- }
- puts("");
- }
- return ;
- }
Map: 4227ms
- #include<bits/stdc++.h>
- #define rep(i,a,b) for(int i=a;i<=b;i++)
- using namespace std;
- const int maxn=;
- map<string, int>Map;
- int f[maxn];
- vector<int>ans;
- int main()
- {
- int T;
- scanf("%d", &T);
- while(T--)
- {
- int N,x,y;
- string s;
- scanf("%d",&N);
- rep(i,,N){
- cin>>s;
- Map[s]=i;
- }
- rep(i,,N){
- cin >> s;
- f[Map[s]] = i;
- }
- rep(i,,N){
- if(i==f[i]) printf("1 ");
- else{
- int maxx = f[i];
- for(int j = i + ; j <= maxx; j++){
- if(f[j] > maxx)maxx = f[j];
- }
- printf("%d ",maxx-i+);
- i = maxx;
- }
- }
- puts("");
- }
- return ;
- }
unordered_map:2479ms
- #include<bits/stdc++.h>
- #define rep(i,a,b) for(int i=a;i<=b;i++)
- using namespace std;
- const int maxn=;
- unordered_map<string, int>Map;
- int f[maxn];
- int main()
- {
- int T;
- scanf("%d", &T);
- while(T--)
- {
- Map.clear();
- int N,x,y;
- string s;
- scanf("%d",&N);
- rep(i,,N){
- cin>>s;
- Map[s]=i;
- }
- rep(i,,N){
- cin >> s;
- f[Map[s]] = i;
- }
- rep(i,,N){
- if(i==f[i]) printf("1 ");
- else{
- int maxx = f[i];
- for(int j = i + ; j <= maxx; j++){
- if(f[j] > maxx)maxx = f[j];
- }
- printf("%d ",maxx-i+);
- i = maxx;
- }
- }
- puts("");
- }
- return ;
- }
这告诉我们map的效率和map的大小有关,所以要及时的clear。 而我如果用set,一位set一直在erase,元素会慢慢表少,所以二分的速度会更快。
set: 3010ms
- #include<bits/stdc++.h>
- #define rep(i,a,b) for(int i=a;i<=b;i++)
- using namespace std;
- const int maxn=;
- set<string>s;
- string a[maxn],b[maxn];
- int main()
- {
- int T;
- scanf("%d", &T);
- while(T--)
- {
- int N,x,y,tot=;
- scanf("%d",&N);
- rep(i,,N) cin>>a[i];
- rep(i,,N) cin>>b[i];
- rep(i,,N) {
- tot++;
- if(s.find(a[i])!=s.end()) s.erase(a[i]);
- else s.insert(a[i]);
- if(s.find(b[i])!=s.end()) s.erase(b[i]);
- else s.insert(b[i]);
- if(s.empty()) {
- printf("%d ",tot);
- tot=;
- }
- }
- puts("");
- }
- return ;
- }
(但是主要的时间还是在输入输出那里。
W .Wormhole
pro:给定三维的N个点,有一些点对可以互通,其他的点对距离是欧几里得距离。Q次询问点对最近距离。
sol:folyd。
- #include<bits/stdc++.h>
- #define rep(i,a,b) for(int i=a;i<=b;i++)
- using namespace std;
- const int maxn=;
- typedef long long ll;
- struct node
- {
- double x, y, z;
- double operator - (const node& a)const
- {
- return (sqrt((x - a.x) * (x - a.x) + (y - a.y) * (y - a.y) + (z - a.z) * (z - a.z)));
- }
- }a[maxn];
- map<string, int>Map;
- double dis[][];
- int main()
- {
- int T, cases = ;
- scanf("%d", &T);
- while(T--)
- {
- memset(dis, , sizeof(dis));
- Map.clear();
- int n, m;
- scanf("%d", &n);
- string s, s1;
- for(int i = ; i <= n; i++)
- {
- cin >> s >> a[i].x >> a[i].y >> a[i].z;
- Map[s] = i;
- }
- for(int i = ; i <= n; i++)
- {
- for(int j = i + ; j <= n; j++)
- {
- dis[i][j] = dis[j][i] = a[i] - a[j];
- //cout<<dis[i][j]<<endl;
- }
- }
- cin >> m;
- while(m--)
- {
- cin >> s >> s1;
- dis[Map[s]][Map[s1]] = ;
- }
- for(int k = ; k <= n; k++)
- for(int i = ; i <= n; i++)
- for(int j = ; j <= n; j++)
- dis[i][j] = min(dis[i][j], dis[i][k] + dis[k][j]);
- cin >> m;
- cout<<"Case "<<++cases<<":\n";
- while(m--)
- {
- cin >> s >> s1;
- cout<<"The distance from "<<s<<" to "<<s1<<" is "<<(ll)(dis[Map[s]][Map[s1]]+0.5)<<" parsecs.\n";
- }
- }
- return ;
- }
V .Towers
pro:给定N,让填数独,然后给出(N+2)*(N+2)的矩阵,里面N*N的数字或者未知,周围4行表示从那个方向看过去的LIS。N<=5
sol:搜索,需要及时减枝。 check函数就是给个方向的判定。 只跑了30ms,估计包本来就可以暴力一点,即到了边界再减枝?
减枝1:对于每填一个数,就看和上面的数字是否有重复。
减枝2:对于每个数,看左边和上边看过去的LIS已经超过题目描述,退出。
判定3:对于右边界和下边界,检查从右和下看过去的LIS。
- #include<bits/stdc++.h>
- #define ll long long
- #define rep(i,a,b) for(int i=a;i<=b;i++)
- using namespace std;
- const int maxn=;
- char c[][],ans[][];
- int vis[][],N;
- int get(int x,int y,int tx,int ty,int X,int Y)
- {
- int res=,now=;
- while(){
- x+=tx; y+=ty;
- if(ans[x][y]>now) now=ans[x][y],res++;
- if(x==X&&y==Y) return res;
- }
- return res;
- }
- bool check(int u,int v)
- {
- rep(i,,u-) if(ans[u][v]==ans[i][v]) return false;
- if(c[u][]!='-'){
- int t=get(u,,,,u,v);
- if(t>c[u][]-'') return false;
- if(v==N&&t!=c[u][]-'') return false;
- }
- if(c[][v]!='-'){
- int t=get(,v,,,u,v);
- if(t>c[][v]-'') return false;
- if(u==N&&t!=c[][v]-'') return false;
- }
- if(v==N&&c[u][N+]!='-'){
- if(get(u,N+,,-,u,)!=c[u][N+]-'') return false;
- }
- if(u==N&&c[N+][v]!='-'){
- if(get(N+,v,-,,,v)!=c[N+][v]-'') return false;
- }
- return true;
- }
- bool dfs(int u,int v)
- {
- if(u==N+&&v==) {
- return true;
- }
- int L=,R=N;
- if(c[u][v]!='-') L=R=c[u][v]-'';
- rep(i,L,R){
- if(!vis[u][i]){
- vis[u][i]=; ans[u][v]=i;
- if(v<N){
- if(check(u,v)){
- if(dfs(u,v+)) return true;
- }
- }
- else{
- if(check(u,v))
- {
- if(dfs(u+,)) return true;
- }
- }
- vis[u][i]=;
- }
- }
- return false;
- }
- int main()
- {
- int T;
- scanf("%d",&T);
- while(T--){
- scanf("%d",&N);
- memset(vis,,sizeof(vis));
- rep(i,,N+) scanf("%s",c[i]);
- if(!dfs(,)) puts("no\n");
- else {
- rep(i,,N) {
- rep(j,,N) putchar(ans[i][j]+'');
- puts("");
- }
- puts("");
- }
- }
- return ;
- }
T .Runes
pro:给定等式,其中有不超过6个问号,让你填一个相同的未出现过的数字,使等式满足。
sol:枚举。注意负号,0等情况。
- #include<bits/stdc++.h>
- #define rep(i,a,b) for(int i=a;i<=b;i++)
- using namespace std;
- const int maxn=;
- typedef long long ll;
- bool judge(char s[], int x, ll& y)
- {
- int n = strlen(s);
- char s1[];
- memcpy(s1, s, sizeof(s1));
- for(int i = ; i < n; i++)
- {
- if(s1[i] == '?')s1[i] = '' + x;
- }
- if(s1[] == '-' && s1[] == '')return false;
- if(s1[] == '' && n != )return false;
- bool flag;
- if(s1[] == '-')flag = ;
- else flag = ;
- y = ;
- for(int i = flag; i < n; i++)y = y * + s1[i] - '';
- if(flag)y = -y;
- }
- char s[], s1[], s2[], s3[];
- int vis[];
- int main()
- {
- int T, cases = ;
- scanf("%d", &T);
- while(T--)
- {
- memset(s1, , sizeof(s1));
- memset(s2, , sizeof(s2));
- memset(s3, , sizeof(s3));
- memset(vis, , sizeof(vis));
- scanf("%s", s);
- int n = strlen(s), tmp, tmp1;
- for(int i = ; i < n; i++)
- {
- if((isdigit(s[i]) || s[i] == '?') && (s[i + ] == '+' || s[i + ] == '-' || s[i + ] == '*'))
- {
- tmp = i + ;
- break;
- }
- }
- for(int i = ; i < n; i++)if(s[i] == '='){tmp1 = i;break;}
- for(int i = ; i < n; i++)if(isdigit(s[i]))vis[s[i] - ''] = ;
- for(int i = ; i < tmp; i++)s1[i] = s[i];
- for(int i = tmp + , j = ; i < tmp1; i++, j++)s2[j] = s[i];
- for(int i = tmp1 + , j = ; i < n; i++, j++)s3[j] = s[i];
- bool ok = ;
- for(int i = ; i <= ; i++)
- {
- if(vis[i])continue;
- ll a, b, c;
- bool flag = ;
- if(judge(s1, i, a) && judge(s2, i, b) && judge(s3, i, c))
- {
- if(s[tmp] == '-' && a - b == c)flag = ;
- if(s[tmp] == '+' && a + b == c)flag = ;
- if(s[tmp] == '*' && a * b == c)flag = ;
- }
- if(flag)
- {
- ok = ;
- printf("%d\n", i);
- break;
- }
- }
- if(!ok)printf("-1\n");
- }
- return ;
- }
Q .Number Game
pro:双人博弈,给定一个N的排列,Alice先手,Bob后手,他们轮流取,取到数字1的胜,能取走一个数字的条件是两旁没有比它大的数字。
sol:我们发现,只有和1相邻的连续区间是要考虑的; 之外的区间因为一定可以按一定顺序取完,所以只考虑奇偶性。
即用dp[L][R][k]保存先手的情况:[L,R]是当前包含数字1的区间,k是此区间外的未取的个数奇偶性。然后就可以记忆化搜索了。
- #include<bits/stdc++.h>
- #define rep(i,a,b) for(int i=a;i<=b;i++)
- using namespace std;
- const int maxn=;
- int dp[maxn][maxn][],a[maxn],pos;
- int dfs(int L,int R,int k)
- {
- if(L==R) return ;
- if(dp[L][R][k]!=-)
- return dp[L][R][k];
- if(k==&&!dfs(L,R,)) dp[L][R][k]=;
- rep(i,L,R){
- bool F=true;
- if(i->=L&&a[i-]>a[i]) F=false;
- if(i+<=R&&a[i+]>a[i]) F=false;
- if(!F) continue;
- if(i==pos) dp[L][R][k]=;
- else {
- if(i<pos){
- if(!dfs(i+,R,(k+i-L)&)) dp[L][R][k]=;
- }
- else {
- if(!dfs(L,i-,(k+R-i)&)) dp[L][R][k]=;
- }
- }
- }
- if(dp[L][R][k]==-) dp[L][R][k]=;
- return dp[L][R][k];
- }
- int main()
- {
- int N,T;
- scanf("%d",&T);
- while(T--){
- scanf("%d",&N);
- rep(i,,N){
- scanf("%d",&a[i]);
- if(a[i]==) pos=i;
- }
- memset(dp,-,sizeof(dp));
- dfs(,N,);
- if(dp[][N][]) puts("Alice");
- else puts("Bob");
- }
- return ;
- }
Gym-101653:acific Northwest Regional Contest (2019训练第一场)的更多相关文章
- 2020.5.4-ICPC Pacific Northwest Regional Contest 2019
A. Radio Prize All boring tree-shaped lands are alike, while all exciting tree-shaped lands are exci ...
- 2018-2019 ACM-ICPC Pacific Northwest Regional Contest (Div. 1)
2018-2019 ACM-ICPC Pacific Northwest Regional Contest (Div. 1) 思路: A Exam 思路:水题 代码: #include<bits ...
- 2018 ICPC Pacific Northwest Regional Contest I-Inversions 题解
题目链接: 2018 ICPC Pacific Northwest Regional Contest - I-Inversions 题意 给出一个长度为\(n\)的序列,其中的数字介于0-k之间,为0 ...
- Gym 101655:2013Pacific Northwest Regional Contest(寒假自训第13场)
A .Assignments 题意:给定距离D,以及N个飞机的速度Vi,单位时间耗油量Fi,总油量Ci.问有多少飞机可以到达目的地. 思路:即问多少飞机满足(Ci/Fi)*Vi>=D ---- ...
- Gym - 101615J Grid Coloring DP 2017-2018 ACM-ICPC Pacific Northwest Regional Contest (Div. 1)
题目传送门 题目大意: 给出n*m的网格,有红蓝两种颜色,每个格子都必须被染色,当一个格子被染成蓝色后,这个格子左上方的一块都必须被染成蓝色,问最后的方案数量. 思路: 按照题目条件,如果有一个格子被 ...
- Gym - 101982A 2018-2019 ACM-ICPC Pacific Northwest Regional Contest (Div. 1) A. Exam
题面 题意:你和朋友一起做了n道判断题,现在你知道你们两的答案,也知道你朋友对了k个,问你至少对了几个 题解:假设你和朋友n个答案都一样,那你是不是也对了k个,假设你和朋友有1个答案不一样,是不是,你 ...
- Gym - 101982B 2018-2019 ACM-ICPC Pacific Northwest Regional Contest (Div. 1) B. Coprime Integers Mobius+容斥 ab间gcd(x,y)=1的对数
题面 题意:给你 abcd(1e7),求a<=x<=b,c<=y<=d的,gcd(x,y)=1的数量 题解:经典题目,求从1的到n中选x,从1到m中选y的,gcd(x,y)=k ...
- 2015-2016 ACM-ICPC Pacific Northwest Regional Contest (Div. 2) S Surf
SurfNow that you've come to Florida and taken up surng, you love it! Of course, you've realized that ...
- Contest Setting 2018 ICPC Pacific Northwest Regional Contest dp
题目:https://vj.69fa.cn/12703be72f729288b4cced17e2501850?v=1552995458 dp这个题目网上说是dp+离散化这个题目要对这些数字先处理然后进 ...
随机推荐
- 大量的QT控件及示例发放
QT属性控件项目https://github.com/lexxmark/QtnProperty 比特币交易软件https://github.com/JulyIGHOR/QtBitcoinTrader ...
- jQuery滚屏插件XSwitch.js
1.需要有基本的HTML结构 <div style="margin-top: 124px;" id="container" data-XSwitch> ...
- 尚学堂java 参考答案 第七章
本答案为本人个人编辑,仅供参考,如果读者发现,请私信本人或在下方评论,提醒本人修改 一.选择题 1.ACD 解析:B:java中左边不能直接直接指定长度,和C语言不一样 2.B 3.C 解析:B各行分 ...
- Vue笔记:使用 vuex 管理应用状态
如果你在使用 vue.js , 那么我想你可能会对 vue 组件之间的通信感到崩溃 . 我在使用基于 vue.js 2.0 的UI框架 ElementUI 开发网站的时候 , 就遇到了这种问题 : 一 ...
- xadmin后台导出时gunicorn报错ascii
django + xadmin + nginx + gunicorn部署后,xadmin后台导出model数据报错,gunicorn日志记录为:UnicodeEncodeError: 'ascii' ...
- day18 类与类之间的关系
今日所学内容: 1.类与类之间的关系 2.self 到底是谁? 3. 特殊成员 : 1.类与类之间的关系 在我们的世界中事物和事物之前总会有一些联系 在面向对象中,类与类之间也可以产生相关的联系 1) ...
- 《Python》网络编程之验证客户端连接的合法性、socketserver模块
一.socket的更多方法介绍 # 服务端套接字函数 s.bind() # 绑定(主机,端口号)到套接字 s.listen() # 开始TCP监听 s.accept() # 被动接受TCP客户的连接, ...
- 下载hibenate tools插件(百度搜hibenate tools 下载)
Eclipse插件的安装和使用1. 在线更新( http://blog.csdn.net/charlies_fu/article/details/5638068)打开eclipse工具,选择H ...
- SQL-25 获取员工其当前的薪水比其manager当前薪水还高的相关信息
题目描述 获取员工其当前的薪水比其manager当前薪水还高的相关信息,当前表示to_date='9999-01-01',结果第一列给出员工的emp_no,第二列给出其manager的manager_ ...
- 玩转X-CTR100 l STM32F4 l AT24C02 EEPROM存储
我造轮子,你造车,创客一起造起来!塔克创新资讯[塔克社区 www.xtark.cn ][塔克博客 www.cnblogs.com/xtark/ ] 本文介绍X-CTR100控制器 板载EEP ...