Codeforces Round #345 (Div. 2)

来源:互联网 发布:战舰世界详细数据 编辑:程序博客网 时间:2024/06/06 16:25

链接:http://codeforces.com/contest/651

A. Joysticks

题意:两个游戏手柄一个充电器,每次只能冲一个手柄,再冲电的每分钟涨1%,没冲的掉2%,两个都到%1以下游戏结束,问什么时候结束。

分析:哪个的电量低哪个就冲电。
代码:
#include<algorithm>#include<iostream>#include<cstring>#include<cstdio>#include<string>#include<vector>#include<queue>#include<cmath>#include<stack>#include<set>#include<map>#define INF 0x3f3f3f3f#define Mn 50010#define Mm 2000005#define mod 1000000007#define CLR(a,b) memset((a),(b),sizeof((a)))#define CPY(a,b) memcpy ((a), (b), sizeof((a)))#pragma comment(linker, "/STACK:102400000,102400000")#define ul u<<1#define ur (u<<1)|1using namespace std;typedef long long ll;int read() {    char c=getchar();    int re=0,f=1;    while(c<'0'||c>'9') {if(c=='-') f=-1;c=getchar();}    while(c>='0'&&c<='9') {re=re*10+c-'0';c=getchar();}    return re;}int main() {    int n=read(),m=read();    int a,b;    int num=0;    while(1) {        if(n>m) {            n-=2;            if(n<0||m==0) break;            m++;        } else {            m-=2;            if(m<0||n==0) break;            n++;        }        num++;    }      cout<<num<<endl;    return 0;}
B. Beautiful Paintings

题意:一个序列中的元素前一个小于后一个,答案加1,求随意摆放后答案最大。。

分析:记录每个数的个数,然后离散化,这时计算每个数对后面的贡献。


#include<algorithm>#include<iostream>#include<cstring>#include<cstdio>#include<string>#include<vector>#include<queue>#include<cmath>#include<stack>#include<set>#include<map>#define INF 0x3f3f3f3f#define Mn 1010#define Mm 2000005#define mod 1000000007#define CLR(a,b) memset((a),(b),sizeof((a)))#define CPY(a,b) memcpy ((a), (b), sizeof((a)))#pragma comment(linker, "/STACK:102400000,102400000")#define ul u<<1#define ur (u<<1)|1using namespace std;typedef long long ll;int read() {    char c=getchar();    int re=0,f=1;    while(c<'0'||c>'9') {if(c=='-') f=-1;c=getchar();}    while(c>='0'&&c<='9') {re=re*10+c-'0';c=getchar();}    return re;}int num[Mn];int a[Mn];int main() {    int n=read();    for(int i=0;i<n;i++) {        a[i]=read();        num[a[i]]++;    }        sort(a,a+n);    int cnt=unique(a,a+n)-a;for(int i=0;i<cnt;i++) a[i]=num[a[i]];    int sum=0;    for(int i=0;i<cnt;i++) {        if(a[i]==0) continue;        for(int j=i+1;j<cnt;j++) {            if(a[i]>=a[j]) {                sum+=a[j];                a[j]=0;            } else sum+=a[i],a[j]-=a[i];        }    }    cout<<sum<<endl;    return 0;}

C. Watchmen
题意:求二维坐标中满足 |xi - xj| + |yi - yj|=.的点对个数。

分析:用map分别记录在同一横坐标,同一纵坐标,重点个数,用组合数求出在减去重复的。

#include<algorithm>#include<iostream>#include<cstring>#include<cstdio>#include<string>#include<vector>#include<queue>#include<cmath>#include<stack>#include<set>#include<map>#define INF 0x3f3f3f3f#define Mn 1010#define Mm 2000005#define mod 1000000007#define CLR(a,b) memset((a),(b),sizeof((a)))#define CPY(a,b) memcpy ((a), (b), sizeof((a)))#pragma comment(linker, "/STACK:102400000,102400000")#define ul u<<1#define ur (u<<1)|1using namespace std;typedef long long ll;int read() {    char c=getchar();    int re=0,f=1;    while(c<'0'||c>'9') {if(c=='-') f=-1;c=getchar();}    while(c>='0'&&c<='9') {re=re*10+c-'0';c=getchar();}    return re*f;}map<int,int> mp1,mp2;map<pair<int,int>,int>mp3;int main() {    int n=read();    for(int i=0;i<n;i++) {        int x=read(),y=read();        mp1[x]++;        mp2[y]++;        mp3[make_pair(x,y)]++;    }        ll ans=0;    for(auto it:mp1)  {       int k=it.second;       ans+=(ll)k*(k-1);}    for(auto it:mp2)  {       int k=it.second;       ans+=(ll)k*(k-1);}    for(auto it:mp3)  {       int k=it.second;       ans-=(ll)k*(k-1);}    cout<<ans/2<<endl;    return 0;}

D. Image Preview

题意:手机看照片,w为横放,h为竖放,对于没看过的照片要先用1秒看是w还是h,如果是w,就必须花费b秒变成h,照片切换要花费a秒。看过的照片不需要看的时间个转换时间。不能跳过没看的照片。

分析:先预处理出从一边开始到极限经过的每张照片花费时间。然后每次回退这一边的点,将多出来的时间用到另一边,因为回退过程中,多出来时将总是增加的,是所以另一边可以在上次回退的基础上继续走。时间复杂度o(n).

#include<algorithm>#include<iostream>#include<cstring>#include<cstdio>#include<string>#include<vector>#include<queue>#include<cmath>#include<stack>#include<set>#include<map>#define INF 0x3f3f3f3f#define Mn 500005#define Mm 2000005#define mod 1000000007#define CLR(a,b) memset((a),(b),sizeof((a)))#define CPY(a,b) memcpy ((a), (b), sizeof((a)))#pragma comment(linker, "/STACK:102400000,102400000")#define ul u<<1#define ur (u<<1)|1using namespace std;typedef long long ll;int read() {    char c=getchar();    int re=0,f=1;    while(c<'0'||c>'9') {if(c=='-') f=-1;c=getchar();}    while(c>='0'&&c<='9') {re=re*10+c-'0';c=getchar();}    return re*f;}int th[Mn];int n,a,b,t;int get(string &s) {    int lnum=0,lnt=0,rnum=0,rnt=0;    for(int i=0;i<n;i++) {        if(s[i]=='h') lnt+=1;        else lnt+=b+1;        if(lnt>t) break;        lnum++;th[i]=lnt;lnt+=a;    }    int nowpos=n-1,maxx=lnum;    for(int i=lnum-1;i>=0;i--) {        int rt=t-th[i]-(i+1)*a;          while(1) {         int tmp=rnt;            if(s[nowpos]=='h') rnt+=1;            else rnt+=b+1;            if(rnt>rt) {rnt=tmp;break;}            rnum++;            rnt+=a;nowpos--;            if(nowpos==0) break;        }        maxx=max(maxx,lnum+rnum);        if(maxx>=n) {            maxx=n;            break;        }        lnum--;    }    return maxx;}int main() {    n=read(),a=read(),b=read(),t=read();    string s,x;    cin>>s;    x=s;    reverse(x.begin(), x.end());    x=s[0]+x;    int ans=max(get(s),get(x));    cout<<ans<<endl;    return 0;}


E. Table Compression

题意:将a矩阵转换成另一个矩阵b。要求每行每列不改变相对大小顺序,且每行每列相等的转换后还是相等。

分析:将每行每列相等的点连边,将原值排序后,从小到大求出这些点可在各自的行列可行的最大值,然后得到答案,更新行列值。

代码:

#include<algorithm>#include<iostream>#include<cstring>#include<cstdio>#include<string>#include<vector>#include<queue>#include<cmath>#include<stack>#include<set>#include<map>#define INF 0x3f3f3f3f#define Mn 1000010#define Mm 2000005#define mod 1000000007#define CLR(a,b) memset((a),(b),sizeof((a)))#define CPY(a,b) memcpy ((a), (b), sizeof((a)))#pragma comment(linker, "/STACK:102400000,102400000")#define ul u<<1#define ur (u<<1)|1using namespace std;typedef long long ll;int read() {    char c=getchar();    int re=0,f=1;    while(c<'0'||c>'9') {if(c=='-') f=-1;c=getchar();}    while(c>='0'&&c<='9') {re=re*10+c-'0';c=getchar();}    return re*f;}int h[Mn],w[Mn],vis[Mn],ans[Mn];struct edge {    int next,v;}e[4*Mn];struct node{    int pos,va;}a[Mn],b[Mn],c[Mn];bool cmp(node x,node y) {    return x.va<y.va;}int tot=0,head[Mn];void addedge(int u,int v) {    e[tot].v=v;    e[tot].next=head[u];    head[u]=tot++;}vector<int> vt;void dfs(int u) {    vt.push_back(u);vis[u]=1;    for(int i=head[u];~i;i=e[i].next) {        int v=e[i].v;        if(vis[v]) continue;        dfs(v);    }}int main() {    int n=read(),m=read();    CLR(head,-1);    for(int i=0;i<n;i++) {///处理行相同        for(int j=0;j<m;j++) {            int x=i*m+j,y=j*n+i;            c[y].va=b[x].va=a[x].va=read();            c[y].pos=b[x].pos=a[x].pos=x;         }        int l=i*m,r=(i+1)*m;        sort(b+l,b+r,cmp);        for(int j=l+1;j<r;j++) {            if(b[j].va==b[j-1].va) {                addedge(b[j-1].pos,b[j].pos);                addedge(b[j].pos,b[j-1].pos);            }        }    }    for(int j=0;j<m;j++) {///处理列相同        int l=j*n,r=(j+1)*n;        sort(c+l,c+r,cmp);        for(int i=l+1;i<r;i++) {            if(c[i].va==c[i-1].va) {                addedge(c[i-1].pos,c[i].pos);                addedge(c[i].pos,c[i-1].pos);            }        }    }    sort(a,a+n*m,cmp);    for(int i=0;i<n*m;i++) {        int pos=a[i].pos;        if(vis[pos]) continue;        dfs(pos);///将有关系的存到一个集合        int th=0;        for(int j=0;j<vt.size();j++) {            th=max(th,max(w[vt[j]/m],h[vt[j]%m]));///得到当前可行最小值        }        for(int j=0;j<vt.size();j++) {///更新            ans[vt[j]]=th+1;            w[vt[j]/m]=th+1;            h[vt[j]%m]=th+1;        }        vt.clear();    }    for(int i=0;i<n*m;i++) {       if((i+1)%m==0) printf("%d\n",ans[i]);        else printf("%d ",ans[i]);    }    return 0;}




0 0
原创粉丝点击