2020icpc上海(重温经典)

  • 导语
  • 涉及的知识点
  • 题目
    • B
    • D
    • G
    • H
    • I
    • M
  • 参考文献

导语

涉及的知识点

思维,几何,搜索

链接:第 45 届国际大学生程序设计竞赛(ICPC)亚洲区域赛(上海)(重现赛)

题目

B

题目大意:一个n×m的地图,每个格子要么有地雷要么为一个数字,该数字代表相邻格子中地雷的个数(相邻的定义为有一个顶点公共,即最多有八个相邻),现在给出两个地图A,B,
(规模都为n×m)现在最多可以修改B中⌊nm/2⌋\lfloor{nm/2}\rfloor⌊nm/2⌋个格子使得所有的数字之和与A相同,输出最后得到的B

思路:首先,题目一定有解,理由很简单,首先有个很简单的结论:A与A的反(即所有元素对应取反)的数字和相同,假设B到A需要X步,如果X小于等于⌊nm/2⌋\lfloor{nm/2}\rfloor⌊nm/2⌋,那么直接从B变到A即可,否则就变到A的反

代码

#include <bits/stdc++.h>
#define ll long long
#define INF 0x3f3f3f3f
using namespace std;
string strs[1005];
string strs2[1005];
int a[8][2]= {{1,0},{1,1},{0,1},{-1,1},{-1,0},{-1,-1},{0,-1},{1,-1}};
int judge(int n,int m) {int ans=0;for(int i=0; i<n; i++)for(int j=0; j<m; j++)if(strs[i][j]!=strs2[i][j])ans++;return ans;
}
void print(int n,int m) {for(int i=0; i<n; i++) {for(int j=0; j<m; j++)printf("%c",strs[i][j]);printf("\n");}
}
void printfan(int n,int m) {for(int i=0; i<n; i++) {for(int j=0; j<m; j++)if(strs[i][j]=='.')printf("X");elseprintf(".");printf("\n");}
}
void solve() {int n,m;scanf("%d%d",&n,&m);int k=n*m/2;for(int i=0; i<n; i++)cin>>strs[i];for(int i=0; i<n; i++)cin>>strs2[i];int base=judge(n,m);if(base<=k)print(n,m);elseprintfan(n,m);
}
int main() {int t = 1;while(t--)solve();return 0;
}

D

题目大意:有一个数轴,范围为[0,n][0,n][0,n],数轴上有两个人,位置和速度为p1,v1,p2,v2p1,v1,p2,v2p1,v1,p2,v2,求出两人路程和能够覆盖数轴的最小时间

思路:一共有四种情况(p1<p2)

  1. p1与p2相向而行
  2. p1走完全程
  3. p2走完全程
  4. p1与p2相背而行,最后走完p1-p2,或者先走完p1-p2,再走完p1和p2

前三种都可以容易的推出结论式,至于为什么不考虑同向而行,因为同向而行所需要的时间必然小于相向而行,并且与对应同向者走完全程的时间是相等的

对于第四种,需要考虑两人在哪里相遇,即考虑是先相遇还是后相遇,相遇的点必然在p1p2之间,在这个区间内二分求得相遇点即可

代码

#include <bits/stdc++.h>
#define ll long long
#define INF 0x3f3f3f3f
using namespace std;
int t;
double n,p1,v1,p2,v2,ans;
bool judge(double pos) {double t1=(min(pos-p1,p1)+pos)/v1,t2=(min(p2-pos,n-p2)+n-pos)/v2;ans=min(ans,max(t1,t2));//这里t1,t2的最小值是不满足条件的,但最大值是满足条件的return fabs(t1-t2)>1e-11&&t1<t2;
}
int main() {scanf("%d",&t);while(t--) {cin >>n>>p1>>v1>>p2>>v2;if(p1>p2&&fabs(p1-p2)>1e-11) {//确保p1为左swap(p1,p2);swap(v1,v2);}ans=1e10;//初始化答案为无穷大ans=min(ans,max((n-p1)/v1,p2/v2));//相向而行ans=min(ans,(min(n-p1,p1)+n)/v1);//p1走完ans=min(ans,(min(n-p2,p2)+n)/v2);//p2走完double l=p1,r=p2;//相对而行,二分交点for(int i=0; i<1000; i++) {//进行多次二分确保精度double mid=(l+r)/2;if(judge(mid))l=mid;else r=mid;}printf("%.10f\n",ans);}return 0;
}

G

题目大意:略

思路:比较简单,与其求有多少个x*y偶数,不如求出有多少个奇数对,直接减去奇数对的个数

代码

#include <bits/stdc++.h>
#define ll long long
#define INF 0x3f3f3f3f
using namespace std;void solve() {ll n;scanf("%lld",&n);ll ans=n*(n-1)/2;ll chu=n/3;ll yu=n%3;ll tmp=0;if(yu==0)tmp=chu*2-1;else if(yu==1)tmp=chu*2;elsetmp=chu*2+1;ll kk=tmp*(tmp+1)/2;ans-=kk;printf("%lld\n",ans);
}
int main() {int t = 1;while(t--)solve();return 0;
}

H

题目大意:一个圆桌,有n个位置,等分分配,有k名客人坐在这n个位置上,有k盘菜分配在这n个位置上,为了使每个客人拿到一个菜,每次可以选择顺时针或逆时针旋转圆桌角度2π/n2\pi/n2π/n,客人遇到菜的时候要么拿走要么等下一个,求出能使每个客人拿到菜消耗的最小时间

思路:易证按照顺序来满足吃菜顺序可得最优解,具体证明可以画一个四个点的证一下或者参考文献

根据贪心的思路,将人与菜的位置进行排序,并且进行k次循环对应,判断当前顺序对应下得到的最优解是多少,对于当前顺序的求解,首先需要特判首尾两点,因为在实现首尾两点的对应关系的过程中,实际上已经实现了其余所有点的对应关系,之后再一 一判断当前点iii先顺时针满足1−i1-i1−i再逆时针满足i+1−ki+1-ki+1−k得到的时间,最后求解出最小值即可

代码

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int maxn=1e4+10;
int t,n,k,a[maxn],v[maxn],b[maxn];
signed main() {ios::sync_with_stdio(0);cin.tie(0);cin >>t;while(t--) {cin >>n>>k;int ans=0x3f3f3f3f;for(int i=0; i<k; i++)cin >>a[i];//存人的位置for(int i=0; i<k; i++)cin >>b[i];//存菜的位置sort(b,b+k);//按照标号升序排列sort(a,a+k);for(int j=0; j<k; j++) {//尝试k种对应方式for(int i=0; i<k; i++)v[i]=(a[(i+j)%k]-b[i]+n)%n;sort(v,v+k);ans=min(ans,min(v[k-1],n-v[0]));//直接满足最远的点,该解一定可行for(int i=1; i<k; i++)ans=min(ans,min(v[i-1],n-v[i])+v[i-1]+n-v[i]);/*以当前对应求解,先顺时针转,使得1-i的到达,再逆时针转使得i+1-k到达*/}cout <<ans<<endl;}return 0;
}

I

题目大意:n个共圆心的圆,半径相差为1,m条线通过圆心将这n个圆平分,求所有交点之间的距离和

思路:

  1. 圆心到其余点的和,易得为∑i=1n2mr\sum_{i=1}^n2mr∑i=1n​2mr,无圆心的话这一部分就不用考虑了
  2. 对于这一层上的距离和,以某点jjj为例,该点到达同一层的其余点kkk需要的距离(除对称点外)都要考虑走弧还是走两个半径,即min(2r,abs(j−k)×2πr/m)min(2r,abs(j-k)×2\pi r/m)min(2r,abs(j−k)×2πr/m),累和加上对称点的距离可得一个点到其余点的距离和为2πr×(m−1)+2mr2\pi r×(m-1)+2mr2πr×(m−1)+2mr,多个圆可得∑i=1n2πr×(m−1)+2mr\sum_{i=1}^n2\pi r×(m-1)+2mr∑i=1n​2πr×(m−1)+2mr
  3. 层与层之间的和可以由高层先到低层,再获得低层彼此之间的最小值即可,其余具体看代码

代码

#include<bits/stdc++.h>
using namespace std;
const double pi = acos(-1);
int n,m;
int main() {scanf("%d%d",&n,&m);double ans=0,point[1212],cir[1212],degree=pi/m;//最后结果,本层一个点到其余点距离和,本层某个点到本层和内部所有的距离和//m条线所成的角度ans+=(m>1)*n*(n+1)*m;//圆心到每个点的距离,大于1用来特判圆心for(int i=1; i<=n; i++) {//逐层进行for(int j=1; j<m; j++)//对于某点,假设为1,计算1到左半圆所有点的距离(除对称点)point[i]+=min(i*2.0,degree*j*i);//走弧还是半径point[i]*=2;//填补右半圆point[i]+=2*i;//加上对称点ans+=point[i]*m;//扩充到当前层每个点ans+=(cir[i-1]+(i-1)*2*m)*2*m;//计算本层圆通向内部的和,(i-1)*2*m是先前i-1层所有的点,2*m是本层的2*m个点cir[i]=cir[i-1]+(i-1)*2*m+point[i];//前缀和处理}printf("%.10f",ans);return 0;
}

M

题目大意:略

思路:题目的关键点是字符串的处理,需要设计一个虚拟的根节点,然后从根节点进行DFS获得每个节点的状况(是否需要保护)

代码

#include <bits/stdc++.h>
#define ll long long
#define INF 0x3f3f3f3f
using namespace std;
const int maxn=2e4+10;
int head[maxn],cnt,n,m;
bool vis[maxn],val[maxn];
struct node
{int to,next;
} e[maxn];
void Add(int to,int from)
{e[++cnt].to=to;e[cnt].next=head[from];head[from]=cnt;
}
bool DFS1(int u)
{bool flag=1,make=0;vis[u]=1;for(int i=head[u]; i; i=e[i].next){int v=e[i].to;if(vis[v])continue;flag&=DFS1(v);make=1;}if(!make)return val[u];return val[u]=flag;
}
int DFS2(int u)
{if(val[u]&&u!=1)return 1;vis[u]=1;int ans=0;for(int i=head[u]; i; i=e[i].next){int v=e[i].to;if(vis[v])continue;ans+=DFS2(v);}return ans;
}
void solve()
{unordered_map<string,int>mp;ios::sync_with_stdio(0);cin.tie(0);cin >>n>>m;int id=1,pre=-1;memset(head,0,sizeof(head));memset(vis,0,sizeof(vis));memset(val,0,sizeof(val));cnt=0;for(int i=1; i<=n; i++){string s,tmp="";cin >>s;int len=s.length();pre=1;for(int j=0; j<len; j++){tmp+=s[j];if(s[j]=='/'){if(mp[tmp]==0){mp[tmp]=++id;Add(pre,id);Add(id,pre);}pre=mp[tmp];}}mp[s]=++id;val[id]=1;Add(pre,id);Add(id,pre);}for(int i=1; i<=m; i++){string s,tmp="";cin >>s;int len=s.length();pre=1;for(int j=0; j<len; j++){tmp+=s[j];if(s[j]=='/'){if(mp[tmp]==0){mp[tmp]=++id;Add(pre,id);Add(id,pre);}pre=mp[tmp];}}mp[s]=++id;Add(pre,id);Add(id,pre);}DFS1(1);memset(vis,0,sizeof(vis));cout <<DFS2(1)<<endl;
}
int main()
{int t;scanf("%d",&t);while(t--){solve();}return 0;
}

参考文献

  1. 2020ICPC(上海) - Walker(分类讨论+二分)
  2. 第 45 届国际大学生程序设计竞赛(ICPC)亚洲区域赛(上海)H Rice Arrangement —— 枚举,思维,有丶东西
  3. 第 45 届国际大学生程序设计竞赛(ICPC)亚洲区域赛(上海) > 题解讨论
  4. 2020上海ICPC H Rice Arrangement(乱搞,思维)
  5. 2020ICPC上海 H. Rice Arrangement

2020icpc上海(重温经典)相关推荐

  1. 2021上海站(重温经典)

    2021上海站(重温经典) 导语 涉及的知识点 题目 D E G I K 参考文献 导语 拿来练手的,好长时间没弄了,生疏了不少,思维和分析需要再加强 涉及的知识点 思维,数学,背包DP,树形DP,K ...

  2. 电影AI修复,让重温经典有了新的可能

    摘要:有没有一种呈现,不以追求商业为第一目的,不用花大价钱,不用翻拍,没有画蛇添足,低成本的可共赏的让经典更清晰? 本文分享自华为云社区<除了重映和翻拍,重温经典的第三种可能>,原文作者: ...

  3. 2017南宁(重温经典)

    2017南宁(重温经典) 导语 涉及的知识点 题目 H I M L 参考文献 导语 这场打的还可以,也学到了二分图的更简单的建图和匹配实现,虽然以前看过,但没有着重关注,这次直接整理了 涉及的知识点 ...

  4. 重温经典:简读光干涉、衍射原理

    如果您不是光学专业的,或者是文科生,那么您想到光的干涉和衍射第一反应应该是很多公式对不对?头好大是不是?好,那么今天我们就不用一个公式来重新解读光的干涉和衍射. 光,也叫电磁波,他的表现形式我们通常用 ...

  5. 2018青岛(重温经典)

    2018青岛(重温经典) 导语 涉及的知识点 题目 C D E F J M 参考文献 导语 难度不高的一次训练,但是还是很考思维的 涉及的知识点 思维,构造,平面几何,搜索 链接:The 2018 A ...

  6. 让我们重温经典---TVB十大感人爱情故事

    让我们重温经典---TVB十大感人爱情故事 此主题相关图片如下: 1.<上海滩>:当许文强中枪后,丁力抱着许文强,许文强临死前说:"你知道我要去哪儿么?我要去找程程." ...

  7. 让电影票房飞一会儿,五一换个姿势重温经典

    距离五一小长假,还有不到20个小时!和我们一起迎接五一的,还有14部影片,号称史上最挤五一档!小编没有说错,"最挤"而不是"最强". 五一电影预售票房已经出炉, ...

  8. linux win95模拟,【重温经典】Windows 95 模拟软件--记忆中的扫雷和纸牌

    软件平台:Windows/Mac os/Linux 今天给大家分享一个东西,虽然没啥卵用... 简单介绍 聊天软件 Slack 的开发者 Felix Rieseberg 把 Windows 95 变成 ...

  9. 【重温经典】MIT人工智能实验室: 如何做研究?丨附下载

    https://dspace.mit.edu/bitstream/handle/1721.1/41487/AI_WP_316.pdf (也可以点击文末" 阅读原文 "链接获取完整文 ...

最新文章

  1. windows客户端安装
  2. 已解决Cause: java.sql.SQLException: Incorrect string value: ‘\\xF0\\x9F\\x8C\\xB8 \\xE5...‘报错
  3. 1.9 Java数组和字符串的相互转换
  4. 查看apache连接数及apache工作原理
  5. java字符串常量池——字符串==比较的一个误区
  6. 用css及jQuery实现的精美拉下菜单导航条
  7. 【最佳实践】企业级 Hotfix 代码合并和系统发版策略
  8. (转)ComputerStyle与currentStyle的区别
  9. CCF201809-4 再卖菜(100分)【DFS】
  10. matlab和pspice,电力电子电路仿真---MATLAB和PSpice应用
  11. Layabox2初学(一)javascript
  12. 什么是双线双IP,什么叫双线双IP
  13. Jenkins环境部署
  14. 非常快速的在ubuntu上搭建openvpn!
  15. 【笨木头Lua专栏】基础补充02:函数的几个特别之处
  16. BUUCTF 异性相吸
  17. 视觉设计师跟平面设计_用户体验设计师应了解的6条视觉设计原则
  18. 微软Win11应用商店功能增强:允许用户备份/修复游戏
  19. vue3+ts issue —— vue.ts 不是模块。
  20. 人生苦短我用python壁纸_人生苦短,我用 Python——我如何用 Python 助力工作和生活?...

热门文章

  1. 纽曼平板 T9 ROOT过程
  2. VS2019 安装MFC
  3. c语言循化,循化骗子
  4. 机创仿生青蛙学习记录day1
  5. C#实现 -- 自动获取剪贴板的文字并且自动发送
  6. 分享些常用的工具网站
  7. 第7讲,国界线与省界线
  8. html 页面QQ 。。。在线交谈
  9. 基于Nodejs的知识信息分享平台的设计和实现
  10. 无关时光无关距离无关悲欢:伤感QQ日志