Educational Codeforces Round 109 (Rated for Div. 2)题解
A
想要你配制一瓶魔法液和水的比例为K:100-K的魔法水
问你最少需要加几次,每次加其中一种的一个单位
即求K和K-100的最大公约数,然后除去最大公约数的和
int k; void solve() { sd(k); int k2=100-k; int g=__gcd(k,k2); k/=g,k2/=g; pd(k+k2); }
B
给你一个长度为n的数组,每次可以将长度小于n的连续数组排序,问你最少需要操作多少次能将数组排列
我们要先将1排在第一个或者将n排在最后一个
如果已经排列好,即答案为0
如果第一个数为1或最后一个数为n,即答案为1
如果第一个数为n且最后一个数为1,即答案为3
其余情况为2
int n,a[maxn]; void solve() { bool ju=0; sd(n); rep(i,1,n) { sd(a[i]); if(a[i]!=i)ju=1; } if(!ju)pd(0); else if(a[1]==1||a[n]==n)pd(1); else if(a[1]==n&&a[n]==1)pd(3); else pd(2); }
C
在[0,m]上有n个机器人,每个机器人有一个初始方向和初始位置
如果两个机器人经过同一个整数点,那么这两个机器人都将报废消失
问你这n个机器人消失的时间
我是先将n个机器人安装位置排列,因为位置奇偶不同的话可能影响会不会炸,所以我根据方向和位置奇偶性存储
如果当前机器人方向为L,则它跟它左边距离它最近的还没炸的奇偶性相同且方向相同的机器人一起炸
如果当前机器人方向为R,则它跟它左边距离它最近的还没炸的奇偶性相同且方向相反的机器人一起炸
然后再处理方向同为R的机器人
(qwq可能被hack,因为没怎么细想
更新:哈哈哈没被hack~~~
!!!代码累赘了!!!
int n,m; struct point{ int x,id; char c; point(){} point(int x,int id,char c):x(x),id(id),c(c){} }p[maxn]; bool cmp(point a,point b) { return a.x<b.x; } vector<point>l[2],r[2]; int ans[maxn]; void solve() { l[0].clear();l[1].clear();r[0].clear();r[1].clear(); sdd(n,m); rep(i,1,n)sd(p[i].x),ans[i]=-1,p[i].id=i; rep(i,1,n) { getchar();scanf("%c",&p[i].c); }//,printf("%d %c\n",i,p[i].c); sort(p+1,p+1+n,cmp); rep(i,1,n) { int jo=p[i].x&1; if(p[i].c=='L') { if(r[jo].size()) { point pp=r[jo].back(); r[jo].pop_back(); ans[pp.id]=ans[p[i].id]=(p[i].x-pp.x)/2; } else if(l[jo].size()) { point pp=l[jo].back(); l[jo].pop_back(); ans[pp.id]=ans[p[i].id]=(p[i].x-pp.x)/2+pp.x; } else l[jo].pb(p[i]); } else r[jo].pb(p[i]); } int si0=r[0].size(); for(int i=si0-1;i>=1;i-=2) { point p1=r[0][i],p2=r[0][i-1]; ans[p1.id]=ans[p2.id]=(p1.x-p2.x)/2+m-p1.x; } int si1=r[1].size(); for(int i=si1-1;i>=1;i-=2) { point p1=r[1][i],p2=r[1][i-1];//pdd(p1.id,p2.id); ans[p1.id]=ans[p2.id]=(p1.x-p2.x)/2+m-p1.x; } if(si0&1) { if(l[0].size()) { point p1=r[0][0],p2=l[0][0]; int tmp=0; bool ju=0; if(m-p1.x>p2.x)//>> { p1.x+=p2.x; if((m&1)==((m-p1.x)&1)) tmp=p1.x/2+m-p1.x+p2.x; } else//<< { p2.x-=(m-p1.x); if(!((m-p2.x)&1)) tmp=(m-p2.x)/2+m-p1.x+p2.x; } if(tmp) ans[p1.id]=ans[p2.id]=tmp,l[0].pop_back(); } if(l[1].size()) { point p1=r[0][0],p2=l[1][0]; int tmp=0; bool ju=0; if(m-p1.x>p2.x)//>> { p1.x+=p2.x; if((m&1)==((m-p1.x)&1)) tmp=p1.x/2+m-p1.x+p2.x; } else//<< { p2.x-=(m-p1.x); if(!((m-p2.x)&1)) tmp=(m-p2.x)/2+m-p1.x+p2.x; } if(tmp) ans[p1.id]=ans[p2.id]=tmp,l[1].pop_back(); } } if(si1&1) { if(l[0].size()) { point p1=r[1][0],p2=l[0][0]; int tmp=0; bool ju=0; if(m-p1.x>p2.x)//>> { p1.x+=p2.x; if((m&1)==((m-p1.x)&1)) tmp=p1.x/2+m-p1.x+p2.x; } else//<< { p2.x-=(m-p1.x); if(!((m-p2.x)&1)) tmp=(m-p2.x)/2+m-p1.x+p2.x; } if(tmp) ans[p1.id]=ans[p2.id]=tmp,l[0].pop_back(); } if(l[1].size()) { point p1=r[1][0],p2=l[1][0]; int tmp=0; bool ju=0; if(m-p1.x>p2.x)//>> { p1.x+=p2.x; if((m&1)==((m-p1.x)&1)) tmp=p1.x/2+m-p1.x+p2.x; } else//<< { p2.x-=(m-p1.x); if(!((m-p2.x)&1)) tmp=(m-p2.x)/2+m-p1.x+p2.x; } if(tmp) ans[p1.id]=ans[p2.id]=tmp,l[1].pop_back();//,pdd(p1.id,p2.id); } } rep(i,1,n)pdk(ans[i]); puts(""); }
D
有n张椅子,有一些椅子上有人坐,可能出于体谅椅子的原因,要你将这些人挪位置,使得之前被人坐过的椅子不能再被人坐,要你求最小时间
典型动态规划
int n,a[maxn]; int dp[maxn][maxn]; //dp[i][j]代表前i个人坐在前j个位 //说明第i个人在第j个位 void solve() { memset(dp,INF,sizeof dp); sd(n); rep(i,1,n)sd(a[i]); rep(i,0,n)dp[0][i]=0; int cur=0; rep(i,1,n) { if(!a[i])continue; ++cur; rep(j,1,n) { if(!a[j])dp[cur][j]=dp[cur-1][j-1]+abs(i-j); dp[cur][j]=min(dp[cur][j],dp[cur][j-1]); } } pd(dp[cur][n]); }
更新: 好像还是第一次收到???
欢迎加我qq1165750856一起玩呀~