2019 ICPC NAC补题
题目链接(PDF):https://cs.baylor.edu/~hamerly/icpc/qualifier_2019/naq2019.pdf
A Circuit Math
题解:后缀表达式,从左到右遍历表达式的每个数字和符号,遇到数字就进栈,遇到符号就将处于栈顶两个数字出栈,进行运算,并将运算结果进栈,直至栈空。
#include<bits/stdc++.h>
using namespace std;int n;
int inp[30];
char ch;
stack<int> s;
string t;int main(){cin >> n;for(int i = 0;i < n; i++){cin >> ch;if(ch=='T') inp[i] = 1;else inp[i] = 0;}getchar();getline(cin, t);stringstream ss(t);char tmp;while(ss>>tmp){if(tmp>='A' && tmp <= 'Z'){s.push(inp[tmp-'A']);}else{int a =s.top(); s.pop();if(tmp=='*'){int b = s.top(); s.pop();s.push(a&b);}else if(tmp=='+'){int b = s.top(); s.pop();s.push(a|b);}else if(tmp=='-'){s.push(1^a);}} }if(s.top()) cout << "T";else cout << "F" ; // system("pause");return 0;
}
B Diagonal Cut
收获:若题干没有明确具体形式, 就按照最容易的形式计算,如本题,将每个小矩形按照正方形处理
题解:若当做正方形处理,则只需要看直线y = MxN\dfrac{Mx}{N}NMx ((0,0)->(N,M))
是否经过正方形中心点即可。
正方形的左下角的点设为(p,q) 则其中心的点为(p+1/2, q+1/2)
即是否满足q + 12\dfrac{1}{2}21 = MN\dfrac{M}{N}NM∗*∗(2p+1) 约分后得 2q+1 = mn\dfrac{m}{n}nm(2p + 1)
显然此时 m n互质 则只有两种情况
一. m n都是奇数
显然式子左边的必然是整数(奇数), 则式子右边也是整数(奇数 所以k也是奇数) 即(2p+1) = kn =》有多少个k符合题意
得 k = 2pn\dfrac{2p}{n}n2p + 1n\dfrac{1}{n}n1 < 2Nn\dfrac{2N}{n}n2N + 1n\dfrac{1}{n}n1 且k为整数 所以k<=2Nn\dfrac{N}{n}nN=2gcd(N,M) 又因为k是奇数所以k有gcd(N,M)个
二. m n中有一个是偶数
n(2q+1) = m(2p + 1) 显然该情况下 式中只有m或n是偶数 其余都是奇数 所以等式不成立
综上所述 return m%2 && n%2 ?gcd(M,N) : 0;
#include<bits/stdc++.h>
using namespace std;typedef unsigned long long ull;
ull n, m;ull gcd(ull a, ull b){return b==0?a:gcd(b, a%b);
}int main(){scanf("%lld%lld",&n,&m);ull d = gcd(n,m);n /= d, m /= d;if(n%2&&m%2) printf("%lld\n",d);else printf("0\n"); //system("pause");return 0;
}
C Gerrymandering
题解:签到题,就是题干有点长,理解题意就做出来了。
#include<bits/stdc++.h>
using namespace std;int n, m, tmp;
int vote[1005][2]={0};
int a, u, v;int main(){int sum = 0;ios::sync_with_stdio(false);cin >> n >> m;for(int i = 0; i < n; i++){cin >> a >> u >> v;vote[a][0] += u;vote[a][1] += v;sum += u+v;}int suma = 0, sumb = 0;for(int i = 1; i <= m; i++){int x, y;if(vote[i][0] > vote[i][1]){x = vote[i][0] - (vote[i][0]+vote[i][1])/2-1;y = vote[i][1];cout << "A";}else {y = vote[i][1] - (vote[i][0]+vote[i][1])/2-1;x = vote[i][0];cout << "B";}cout << " " << x << " " << y << endl;suma += x;sumb += y;}// cout << sum << suma << sumb << endl;printf("%.10f\n", abs(suma-sumb)*1.0/(sum*1.0));// system("pause");return 0;
}
D Missing Numbers
题解:签到题,在读取输入的同时,输出第i与i-1个数之间的数。最后,判断一下n与最后一个数是否相等
#include<bits/stdc++.h>
using namespace std;int n;
int arr[205];
int cnt = 0;int main(){cin >> n;arr[0] = 0;for(int i = 1 ; i <= n; i++){cin >> arr[i];for(int j = arr[i-1]+1; j < arr[i]; j++)cout << j << endl;}if(n==arr[n]) cout << "good job" << endl;// system("pause");return 0;
}
G Research Productivity Index
题解:概率dp,枚举提交k篇卷子,并计算出提交k篇的期望(等于结果*概率)。
用f(i,j)表示提交i份卷子,通过j份的函数值,由题干可得f(i,j)=iijf(i, j )=i^{\frac{i}{j}}f(i,j)=iji(j>0);f(i,j)=0(j=0)。
用dp[i][j]表示提交i份卷子,通过j份的概率。并且从n份卷子选出k份卷子,显然当选出概率前k大的卷子时概率最大。
有dp[i][j]=pi∗dp[i−1][j−1]+(1−pi)∗dp[i−1][j]dp[i][j]=p_{i}*dp[i-1][j-1]+(1-p_{i})*dp[i-1][j]dp[i][j]=pi∗dp[i−1][j−1]+(1−pi)∗dp[i−1][j]。则提交k份卷子的期望就等于∑0k\sum_0^k∑0kf(k,j)*dp[k][j]。提交1-n份卷子的期望最大值即为答案。
#include<bits/stdc++.h>
using namespace std;int n, tmp;
double inp[105];
double dp[105][105];bool cmp(double a, double b){return a>b;
}int main(){ios::sync_with_stdio(false);cin >> n;double ans = 0;for(int i = 1; i <= n; i++){cin >> tmp;inp[i] = tmp*1.0/100;}sort(inp+1, inp+n+1, cmp);//计算提交i份卷子,通过j份的概率dp[0][0] = 1;for(int i = 1; i <= n; i++){dp[i][0] = dp[i-1][0]*(1-inp[i]);}for(int i = 1; i <= n; i++){for(int j = 1; j <= n; j++){dp[i][j] = dp[i-1][j-1]*inp[i] + dp[i-1][j]*(1-inp[i]);}}//计算提交k份卷子的期望for(int i = 1; i <= n; i++){double res = 0;for(int j = 1; j <= i; j++){res += dp[i][j]*pow(j, j*1.0/(i*1.0));}ans = max(ans, res);}printf("%.9f\n", ans);// system("pause");return 0;
}
I Slow Leak
收获:弗洛伊德算法 这篇博客写的挺好的
用二维数组储存节点之间的距离,先将数组初始化((i,i)初始化0,其余初始化为∞)
然后根据输入 将(i,j)的值改为 输入的长度值k 即为任意两点之间的距离(无中转点)
核心算法:将1-n节点分别为中转点 改变两点之间的最短距离
for(int k = 1; k <= n; k++){//枚举中转点for(int i = 1; i <= n; i++){for(int j = 1; j <= n; j++){if(e[i][j] > e[i][k] + e[k][j]){e[i][j] =s e[i][k] + e[k][j];}}}}
题解:先用弗洛伊德算法 在完整图中计算出任意两点之间的最短距离
再建立一个只有起点、终点、修车店的图G’,将包含非G’节点的以及不符合题意的路径长度设为∞
再用一遍弗洛伊德算法算出起始点和终点满足题意的最短距离
#include<bits/stdc++.h>
using namespace std;
#define INF 1e18
typedef long long ll;int n,m,t,d;
int rep[505];
ll table[505][505];//用于储存节点之间的距离bool judge(int x){//判断是否为新图的节点 即起始点 修车店return x==1 || x==n || rep[x];
}void floid(){for(int k = 1; k <= n; k++){for(int i = 1; i <= n; i++){for(int j = 1; j <= n; j++){table[i][j] = min(table[i][j],table[i][k] + table[k][j]);}}}
}int main(){scanf("%d%d%d%d",&n,&m,&t,&d);for(int i = 1; i <= t; i++){int x; scanf("%d",&x);rep[x] = 1;//修车店的节点序号}//初始化for(int i = 1; i <=n; i++){for(int j = 1; j <= n; j++){table[i][j] = INF;}}int u, v, l;for(int i = 1; i <= m; i++){scanf("%d%d%d",&u,&v,&l);table[u][v] = l;table[v][u] = l;}//弗洛伊达算法计算出 任意两点之间的最短距离floid();//新图只包含起始点和修车店 即人要么在起点 要么在修车店for(int i = 1; i <= n; i++){//将所有不满足题意的路径 设为无限大for(int j = 1; j <= n; j++){if(i!=j){if(judge(i)&&judge(j)){//是新图节点if(table[i][j]>d) table[i][j] = INF;//但是到不了continue;}}table[i][j] = INF;// i j不全是新图结点}}//再用一遍弗洛伊达算法floid();//cout << table[2][n] << endl;if(table[1][n]==INF) printf("stuck\n");else printf("%d\n",table[1][n]);//system("pause");return 0;
}
J Stop Counting!
题解:答案要么来自前缀和,要么来自后缀和。
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e6+10;
int n, m;
double inp[maxn], pre[maxn]={0}, suf[maxn]={0};int main(){double ans = 0;ios::sync_with_stdio(false);cin >> n;for(int i = 1; i <= n; i++){cin >> inp[i];pre[i] = pre[i-1] + inp[i];ans = max(pre[i]/(i*1.0), ans);}for(int i=n; i>=1 ;i--){suf[i] = suf[i+1] + inp[i];ans = max(suf[i]/((n-i+1)*1.0), ans);}printf("%.9f\n", ans);// system("pause");return 0;
}
K Summer Trip
题解:暴力,不断枚举起点和终点,若起点和终点相同则结束枚举。虽然看着好像是O(n²),但实际上只有O(26*n)。对于每一次枚举,该串中字母均只出现过一次则count++
#include<bits/stdc++.h>
using namespace std;int n;
int vis[30];
string t;
int ans = 0;int main(){cin >> t;for(int i = 0; i < t.length()-1; i++){//枚举起点memset(vis, 0, sizeof(vis));for(int j = i+1; j<t.length(); j++){//枚举终点if(t[j]==t[i]) break;if(!vis[t[j]-'a']){vis[t[j]-'a'] = 1;ans++;}}}cout << ans << endl;// system("pause");return 0;
}
M Zipline
收获:开平方注意原值的正负; 出现除法 要考虑分母为0的情况(因为这个WA了)
题解:
初始化 g-=r, h-=r,看作是在地面上
最小值无可非议,两点间直线最短,题干中也明确提到是刚性绳(大概),所以不需要考虑松弛拉伸的情况。
最大值有两种求法
法一:对称 orz
任取一根柱子作关于ow的对称点P,连接另一个柱子的顶点形成直线l,l的长度就是最长距离,具体证明我忘了(小学知识orz)
#include<bits/stdc++.h>
using namespace std;typedef unsigned long long ull;int main(){int t; cin>>t;while(t--){double w, g, r, h;cin >> w>>g>>h>>r;//if(g<h) swap(g,h);g -= r, h -= r;double mi = sqrt((g-h)*(g-h)+w*w);double mx = sqrt((g+h)*(g+h)+w*w);printf("%.8lf %.8lf\n",mi,mx);}return 0;
}
法二:求导
我当时的做法,设结点距离左柱子的距离为x,则最大值函数为
f(x) = g2+w2\sqrt{g^2+w^2}g2+w2 + h2+(w−x)2\sqrt{h^2 + (w-x)^2}h2+(w−x)2 ,只需求导等于零求出x即可得到答案(就不求二阶导严格证明了)
f’(x) = xg2+w2\dfrac{x}{\sqrt{g^{2}+w^{2}}}g2+w2x + x−wh2+(w−x)2\dfrac{x-w}{\sqrt{h^2+(w-x)^2}}h2+(w−x)2x−w
导数等于0移项化简开平方可得 x = gwg+h\dfrac{gw}{g+h}g+hgw(分母不为0!!!) 再将x代入最大值函数即可求出答案
#include<bits/stdc++.h>
using namespace std;typedef unsigned long long ull;int main(){int t; cin>>t;while(t--){double w, g, r, h;cin >> w>>g>>h>>r;if(g<h) swap(g,h);g -= r, h -= r;if(g==0&&h==0) printf("%.8lf %.8lf\n",w,w);else{double x = g*w/(g+h); // g x h w-xdouble mi = sqrt((g-h)*(g-h)+w*w);double mx = sqrt(g*g+x*x)+sqrt(h*h+(w-x)*(w-x));printf("%.8lf %.8lf\n",mi,mx);}}//system("pause");return 0;
}
剩下的题 之后再补吧 orz
2019 ICPC NAC补题相关推荐
- 第46届ICPC昆明 补题(热身赛 + 正式赛)(K/D/F/G)
热身赛 A.水题 int t, f, s, p, c;for (int i = 0; i < 2; ++i){cin >> t >> f >> s >& ...
- 2019 ICPC 南京 F题 Paper Grading
题目链接 题意 给一些字符串,一个操作是交换两个串的位置,另一个是问编号介于 [l,r][l,r][l,r] 的字符串,与提问串的最长公共前缀(LCP)至少为 kkk 的个数 题解 将串建立 Trie ...
- 2019 Multi-University Training Contest 7 部分补题
2019 Multi-University Training Contest 7 部分补题 这场比赛三个人一起组队,比赛期间自己感觉并没有奉献多少东西,所以补题.而且总感觉比赛到后期很乏力(没力气那种 ...
- 2016ACM/ICPC亚洲区大连站-补题
2016ACM/ICPC亚洲区大连站-补题 5971-Wrestling Match 题目隐藏条件:除去已经知道的好人和坏人,如果剩余的人恰好被分成两组,即便不知道这两组哪组是好人,也是输出YES 做 ...
- 2019暑期个人排位集训补题--思维题
2019暑期集训思维相关补题集 CodeForces - 768B Code For 1 Gym - 100066B CodeForces - 768B Code For 1 Jon fought b ...
- Good Bye 2019补题记录
Good Bye 2019补题记录 A. Card Game 题目描述 Two players decided to play one interesting card game. There is ...
- 2019 ICPC全国邀请赛(西安)I. Cracking Password(序列检验,BSGS,细节题)
整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 2019 ICPC全国邀请赛(西安)I. Cracking Password Weblink http ...
- 2019 CCPC-Wannafly Winter Camp Day8 (Div2, onsite) 补题记录
一篇来自ACM入门者的补题记录 最近有点懒,想着还有最后一篇博客没完成,是我最大的补题动力. 不过终于在camp过去三个月的时候完成了所有的补题博客,有点欣慰,下一个目标应该是补一补一年前暑期训练的题 ...
- 2019寒假集训第五场(新生场)中石油补题和题解
这场比赛本来我都出去了,然后看到老师发消息又回来了= = 然后做着做着正好mhr大佬在外面有一些事情突然没法比赛,于是就帮他交了两道题看看对不对,便于之后补题,然后还真都对了,下面是题目和解析: 问题 ...
最新文章
- 技术管理:带人和团队管理
- jquery无法删除一级域名cookie
- win10防火墙删除的文件在哪里_Win10系统关闭Windows Defender
- 苹果地图副总裁_Amazon A9副总裁Benoit Dupin加入苹果,负责改善苹果地图搜索服务...
- Python环境下,提高pip安装库速度的方法!
- VNC客户端连接MacOS时一闪而过的解决办法
- 2014年即将过去,2015年即将到来
- 在VS中查看文件是谁签出的
- 计算机管理无法输入密码,光大网银控件已安装但无法输入密码
- 基于简单协同过滤推荐算法职位推荐系统
- 浅谈系统实现层面稳定性保障
- freeswitch呼叫中心之百度MRCP语音合成识别环境搭建
- Python3 shutil(高级文件操作 模块)
- html广告横幅图片,制作漂亮网页横幅广告图片的PS教程
- 公司电脑监控软件究竟有何作用?
- Ubuntu20.04安装vscode打开出现花屏
- fastadmin学习 02权限管理和数据限制
- 外贸新手需做哪些准备?如何开发客户?
- 《炬丰科技-半导体工艺》--技术资料合集十
- 寒假LeetCode打卡
热门文章
- 一个屌丝程序猿的人生(四十七)
- mipi LCD 的CLK时钟频率与像素时钟的关系
- 【DIY】基于OpenMV的STM32追球小车
- Flowable入门系列文章41 - 网关 03
- 软件测试自学吉他app,5个受益匪浅的学习类APP,帮助你提升学习动力
- leaflet入门——地图加载(以arcgis服务为例)
- 苹果分屏软件_必备的优秀软件集合---Mac篇(二)
- 编译原理-----1
- 超微主板IPMI激活升级BIOS的方法
- Optimus: An Efficient Dynamic Resource Scheduler for Deep Learning Clusters(论文笔记)