喵哈哈村的魔法考试 Round #9 (Div.2) 题解
2017-03-20 20:48
483 查看
A题 喵哈哈村的数据筛选游戏
题解:这道题签到题,拿个数组记录一下这个数是否出现过即可。#include<bits/stdc++.h> using namespace std; const int maxn = 1e5+5; int vis[maxn]; int n; int a[maxn]; int main(){ while(cin>>n){ memset(vis,0,sizeof(vis)); for(int i=0;i<n;i++){ cin>>a[i]; } int flag = 0; for(int i=0;i<n;i++){ if(vis[a[i]]==0){ vis[a[i]]=1; if(flag==0){ cout<<a[i],flag=1; } else cout<<" "<<a[i]; } } cout<<endl; } }
B题:喵哈哈村的扔硬币游戏
题解:直接暴力更新应该也能过,这里我提倡一种前缀和的做法,每次操作的时候只要看这个点被更新了奇数次还是偶数次就好了。前缀和的具体方式看代码:
#include<bits/stdc++.h> using namespace std; const int maxn = 1e5+7; int a[maxn]; int main(){ int n,m; scanf("%d%d",&n,&m); for(int i=1;i<=m;i++){ int A,B; scanf("%d%d",&A,&B); a[A]++; a[B+1]--; } int sum = 0; for(int i=1;i<=n;i++){ sum+=a[i]; if(sum%2==0)printf("0"); else printf("1"); } printf("\n"); }
C题:喵哈哈村的三角形游戏
三角插值实际上就是假设三个顶点为p1,p2,p3,那么所有三角形内的点都满足p.x = ap1.x+bp2.x+cp3.x;
p.y = ap1.y+bp2.y+cp3.y;
a+b+c = 1
解这个方程得到a,b,c
然后再算p.w = ap1.w+bp2.w+c*p3.w即可。
判断是否在三角形内部,用计算几何的叉积或者面积法都可以。
#include<bits/stdc++.h> using namespace std; const double eps = 1e-6; double x1,yy1,z1,x2,y2,z2,x3,y3,z3; double x,y; struct node{ double x,y; double w; }p[5]; double dis(node A,node B){ return sqrt((A.x-B.x)*(A.x-B.x)+(A.y-B.y)*(A.y-B.y)); } double area(node A,node B,node C){ double len1 = dis(A,B),len2 = dis(B,C),len3 = dis(A,C); double p = (len1+len2+len3)/2; return sqrt(p*(p-len1)*(p-len2)*(p-len3)); } bool equ(double A,double B){ if(fabs(A-B)<eps)return true; return false; } int main(){ while(cin>>p[0].x>>p[0].y>>p[0].w){ for(int i=1;i<3;i++) cin>>p[i].x>>p[i].y>>p[i].w; cin>>p[3].x>>p[3].y; for(int i=3;i>=0;i--){ p[i].x-=p[0].x; p[i].y-=p[0].y; } if(equ(area(p[0],p[1],p[2]),area(p[0],p[1],p[3])+area(p[0],p[2],p[3])+area(p[1],p[2],p[3]))==false){ cout<<"-1"<<endl; continue; } double B = (p[1].x*p[3].y-p[3].x*p[1].y)/(p[1].x*p[2].y-p[2].x*p[1].y); double A; if(equ(p[1].x,0)==false)A = (p[3].x-B*p[2].x)/p[1].x; else A = (p[3].y-B*p[2].y)/p[1].y; printf("%.2f\n",A*p[1].w+B*p[2].w+(1.0-A-B)*p[0].w); } }
D:喵哈哈村的修路游戏
答案显然为连通块的数量-1,随便拿个东西算连通块的数量就好了。#include<bits/stdc++.h> using namespace std; const int maxn = 1e3+7; vector<int> E[maxn]; int n,m; int vis[maxn],cnt=0; void dfs(int x){ vis[x]=1; for(int i=0;i<E[x].size();i++){ if(!vis[E[x][i]]) dfs(E[x][i]); } } int main(){ cin>>n>>m; for(int i=0;i<m;i++){ int a,b; scanf("%d%d",&a,&b); E[a].push_back(b); E[b].push_back(a); } for(int i=1;i<=n;i++){ if(!vis[i]){ cnt++; dfs(i); } } cout<<cnt-1<<endl; }
E:喵哈哈村的打印机游戏
区间DP,dp[l][r][d]表示区间[l,r],当前底色为d的最小花费。然后枚举中间的节点进行转移就好了,具体看代码,是一道中规中矩的区间DP题目。
#include<bits/stdc++.h> using namespace std; const int maxn = 106; int dp[maxn][maxn][maxn]; const int inf = 1e8; string s; int solve(int l,int r,int d){ if(l>r)return 0; if(s[l]-'A'==d&&l==r)return dp[l][r][d]=0; if(l==r)return dp[l][r][d]=1; if(dp[l][r][d]!=-1)return dp[l][r][d]; dp[l][r][d]=inf; for(int i=0;i<26;i++){ dp[l][r][d]=min(dp[l][r][d],solve(l,r,i)+1); } if(s[l]-'A'==d)dp[l][r][d]=min(dp[l][r][d],solve(l+1,r,d)); if(s[r]-'A'==d)dp[l][r][d]=min(dp[l][r][d],solve(l,r-1,d)); for(int i=l+1;i<r;i++){ if(s[i]-'A'==d){ dp[l][r][d]=min(dp[l][r][d],solve(l,i-1,d)+solve(i+1,r,d)); } } return dp[l][r][d]; } int main(){ while(cin>>s){ memset(dp,-1,sizeof(dp)); cout<<solve(0,s.size()-1,27)<<endl; } }
相关文章推荐
- 喵哈哈村的魔法考试 Round #1 (Div.2) 题解
- 喵哈哈村的魔法考试 Round #11 (Div.2) 题解
- 喵哈哈村的魔法考试 Round #2 (Div.2) 题解
- 喵哈哈村的魔法考试 Round #5 (Div.2) 题解
- 喵哈哈村的魔法考试 Round #15 (Div.2) 题解
- 喵哈哈村的魔法考试 Round #14 (Div.2) 题解
- 喵哈哈村的魔法考试 Round #19 (Div.2) 题解
- 喵哈哈村的魔法考试 Round #13 (Div.2) 题解
- 喵哈哈村的魔法考试 Round #18 (Div.2) 题解
- 喵哈哈村的魔法考试 Round #20 (Div.2) 题解
- 喵哈哈村的魔法考试 Round #1 (Div.2) 题解&源码(A.水+暴力,B.dp+栈)
- 喵哈哈村的魔法考试 Round #12 (Div.2) 题解
- 喵哈哈村的魔法考试 Round #10 (Div.2) 题解
- 喵哈哈村的魔法考试 Round #2 (Div.2) B.喵哈哈村的种花魔法 线段树 区间更新 单点查询
- 喵哈哈村的魔法考试 Round #1 (Div.2) C 喵哈哈村的魔法石(II) 背包dp
- 喵哈哈村的魔法考试 Round #3 (Div.2) 题解
- 喵哈哈村的魔法考试 Round #5 (Div.2) ABCC2
- 喵哈哈村的魔法考试 Round #7 (Div.2) 题解
- 喵哈哈村的魔法考试 Round #8 (Div.2) 题解
- 喵哈哈村的魔法考试 Round #21 (Div.2) 题解