Codeforces Round #222 (Div. 2) ABCD

来源:互联网 发布:建立寝室学生信息表sql 编辑:程序博客网 时间:2024/06/04 18:41

继续总结做过的CF

比赛链接:http://codeforces.com/contest/378

A Playing with Dice

题意:a,b两个数字,扔一个骰子,求分别与a,b求差的绝对值,谁小就谁赢,相等平局,输出每种情况的个数。

#include <cstdio>#include <cmath>int a,b;int Dis (int k){    if (fabs(a-k)<fabs(b-k))        return 1;    else if (fabs(a-k)>fabs(b-k))        return -1;    else        return 0;}int main (){    scanf("%d%d",&a,&b);    {        int sa=0,sm=0,sb=0;        for (int i=1;i<=6;i++)        {            if (Dis(i)==1)                sa++;            if (Dis(i)==-1)                sb++;            if (Dis(i)==0)                sm++;        }        printf("%d %d %d\n",sa,sm,sb);    }    return 0;}
B Semifinals
题意:有2场半决赛,各有n个参与者,一共将有n个参与者进入决赛.我们分别在2场比赛中选前k个直接进入决赛,再将剩下的人放在一起排名,选前n-2k个进入决赛.
在k不定的情况下,求哪些人有机会进入决赛,哪些人没有.
思路:k=0和k=n/2分别代表了两种极限情况,其他情况都在这两种之间,分别处理一下即可

#include <cstdio>#include <cstring>const int N = 100005;int n,a[N],b[N];int an[N],bn[N];void Deal (){int i;for (i=0;i<n/2;i++)an[i]=bn[i]=1;int ida=0,idb=0;for (i=0;i<n;i++)if (a[ida] < b[idb])an[ida++] = 1;elsebn[idb++] = 1;} int main (){    scanf("%d",&n);memset(an,0,sizeof(an));memset(bn,0,sizeof(bn));int i;for (i=0;i<n;i++)scanf("%d%d",&a[i],&b[i]);Deal ();for (i=0;i<n;i++)printf("%d",an[i]);printf("\n");for (i=0;i<n;i++)printf("%d",bn[i]);printf("\n");return 0;}

C Maze
题意:给n*m的迷宫,所有'.'为可以通过的地方(给出时所有'.'都四个方向连通),加入k块墙,另所有'.'依然连通,求方案
貌似我想的稍微复杂了些,这里有个简单的思路 http://blog.csdn.net/wangyuquanliuli/article/details/17675801

#include <cstdio>#include <cstring>#include <queue>using namespace std;#define max(a,b) ((a)>(b)?(a):(b))const int N=505;struct Point{int x,y,step;};char map[N][N];int id[N][N]; //记录每个位置被BFS到时的距离bool visit[N][N];int cal[N*N]; //记录每种距离有多少个点int m,n,k;int dx[]={1,-1,0,0};int dy[]={0,0,1,-1};int OK (int x,int y){return x>=0 && x<n && y>=0 &&y<m && map[x][y]=='.' && visit[x][y]==false;}int BFS (int sx,int sy){Point top,t;queue <Point> Q;memset(visit,false,sizeof(visit));memset(id,0,sizeof(id));top.step=0;top.x=sx;top.y=sy;Q.push(top);visit[top.x][top.y]=true;int m=0; //记录BFS的最远距离while (Q.empty()==false){top=Q.front();Q.pop();for (int i=0;i<4;i++){t.x=top.x+dx[i];t.y=top.y+dy[i];t.step=top.step+1;if (OK(t.x,t.y)){visit[t.x][t.y]=true;id[t.x][t.y]=t.step;m=max(m,t.step);cal[t.step]++;Q.push(t);}}}return m;}int main (){    scanf("%d%d%d",&n,&m,&k);    int i,j;    for (i=0;i<n;i++)        scanf("%s",map[i]);    int sx,sy;    cal[0]++;    bool flag=false;    for (i=0;i<n;i++)    {//找第一个'.'        for (int j=0;j<m;j++)            if (map[i][j]=='.')            {                sx=i;sy=j;                flag=true;                break;            }        if (flag)            break;    }    int limit=BFS(sx,sy);    if (limit == 0)    {        for (i=0;i<n;i++)            printf("%s\n",map[i]);        return 0;    }    int sum=0;    for (i=limit;i>=0;i--)    {//记录在哪些距离上的点可以被填充        if (sum+cal[i]<=k)            sum+=cal[i];        else break;    }    int start=++i,ss=k-sum;//ss记录还需要填充多少点    for (i=0;i<n;i++)        for (j=0;j<m;j++)        {            if (id[i][j]>=start)                map[i][j]='X';            if (ss>0 && id[i][j]==start-1)            {                map[i][j]='X';                ss--;            }        }    for (i=0;i<n;i++)        printf("%s\n",map[i]);return 0;}

D Preparing for the Contest
有m个bug,每个bug有级别,有n个人去修复bug,每个人有能力等级和需求.现在总共有s个费用.求最少天数完成的方法,并且输出方案.
思路:二分+贪心+优先队列优化

#include <cstdio>#include <queue>#include <algorithm>using namespace std;const int N = 100005;int n,m,s;int ans[N];struct Student{int b,c,id;bool operator < (Student b) const{//花费小的优先return c>b.c;}}stu[N]; struct Bug{int a,id;bool operator < (Bug b) const{return a<b.a;}}bug[N]; int cmp (Student a, Student b){return a.b > b.b;}void solve (int time){int limit=s,cnt=0;priority_queue <Student> Q;for (int i=m-1;i>=0;i-=time){while (stu[cnt].b >= bug[i].a && cnt != n)Q.push(stu[cnt++]);Student t = Q.top();Q.pop();limit -= t.c;int e=i-time+1;if (e<0) e=0;for (int j=i; j>=e ;j--)ans[bug[j].id] = t.id;}} bool OK (int time){int limit=s, cnt=0;priority_queue<Student> Q;for (int i=m-1;i>=0;i-=time){        while (stu[cnt].b >= bug[i].a && cnt != n)Q.push(stu[cnt++]);//将所有能解决该问题的学生放入优先队列,花费小的优先        if (Q.empty()) return false;        Student t = Q.top();Q.pop();        if (limit < t.c) return false;        limit -= t.c;}return true;} void Deal (){if (OK(m)==false){printf("NO\n");return;}int low=0,high=m,tmp;/*while (low < high) //这么写也可以{int mid=(low+high)>>1;if (OK(mid)) high=mid;else low=mid+1;}solve(high);*/while (low <= high){int mid=(low+high)>>1;if (OK(mid)) high=mid-1,tmp=mid;else low=mid+1;}solve(tmp);printf("YES\n");for (int i=0;i<m;i++)printf(i==m-1?"%d\n":"%d ",ans[i]+1);} int main (){int i;scanf("%d%d%d",&n,&m,&s);for (i=0;i<m;i++){scanf("%d",&bug[i].a);bug[i].id=i;}for (i=0;i<n;i++){scanf("%d",&stu[i].b);stu[i].id=i;}for (i=0;i<n;i++)scanf("%d", &stu[i].c);sort(bug, bug+m); //按照等级降序排序sort(stu, stu+n, cmp); //按照能力升序排序Deal ();return 0;}



0 0