Codeforces Round #516 (Div. 2, by Moscow Team Olympiad)

比赛链接

A Make a triangle!

题意

三根棍子,你可以使任意的一根棍子长度加一,问至少要操作几次才能使这三根棍子能构成一个三角形。

题解

不需要循环的题[手动幽灵]。就不说了吧…

//Leo
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
int a[4],ans,s1;

inline int read()
{
    int x=0,f=1;char ch=getchar();
    while(ch<'0' || ch>'9'){if(ch=='-') f=-1;ch=getchar();}
    while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}

int main()
{
    a[1]=read();a[2]=read();a[3]=read();
    if(a[1]>a[2]) swap(a[1],a[2]);
    if(a[1]>a[3]) swap(a[1],a[3]);
    if(a[2]>a[3]) swap(a[2],a[3]);
    s1=a[1]+a[2];
    if(s1>a[3]) ans=0;else ans=a[3]-s1+1;
    printf("%d\n",ans);
    return 0;
}

B Equations of Mathematical Magic

枚举子集(强行猜?
所以过得比较快。

//Leo
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
int x,Q,res;

inline int read()
{
    int x=0,f=1;char ch=getchar();
    while(ch<'0' || ch>'9'){if(ch=='-') f=-1;ch=getchar();}
    while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}

int main()
{
    Q=read();
    while (Q--){
        x=read();
        res=0;
        while(x){
            if(x&1) res++;
            x>>=1;
        }
        printf("%d\n",1<<res);
    }
    return 0;
}

C Oh Those Palindromes

题意

给你一个长度为n的字符串,给它重新排列使得包含的回文串个数最多。

题解

继续猜结论,一样的字母放在一起输出。

//Leo
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
char ch;
int n,num[100];

int main()
{
    scanf("%d\n",&n);
    for(int i=1;i<=n;i++){
        ch=getchar();
        num[ch-'a']++;
    }
    for(int i=0;i<=25;i++)
        for(int j=1;j<=num[i];j++) putchar(i+'a');
    puts("");
    return 0;
}

D Labyrinth

题意

给你一张n*m的图,从(r,c)开始走,最多向左走x步,最多向右走y步,问能到达多少个点。

题解

于是比赛结束后这题就WA了,还有好多人比赛的时候就被hack了(性质相同?
写了一个最普通的bfs于是过了pretest…
解法1、Dijkstra,处理出起点到每个点要横向走的最小步数。然后根据坐标就能算出向左走几步,向右走几步,判断即可。

//Suplex
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
using namespace std;
const int inf=1e9;
int n,m,Sx,Sy,Sl,Sr,ans;
char st[2020][2020];
int dis[2020][2020];
int vis[2020][2020];
int dx[5],dy[5];

struct leo{
    int d,x,y;
};
struct cmp{
    bool operator () (leo a,leo b) {return a.d>b.d;}
};
priority_queue<leo,vector<leo>,cmp> q;

void Dijkstra()
{
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++) dis[i][j]=inf,vis[i][j]=0;
    while(!q.empty()) q.pop();
    dis[Sx][Sy]=0;
    q.push((leo){0,Sx,Sy});
    while(!q.empty()){
        int x=q.top().x,y=q.top().y;q.pop();
        if(vis[x][y]) continue;
        vis[x][y]=1;
        for(int i=1;i<=4;i++){
            int X=x+dx[i],Y=y+dy[i];
            if(X<1 || X>n || Y<1 || Y>m || st[X][Y]=='*') continue;
            if(dis[X][Y]>dis[x][y]+(i<=2)){
                dis[X][Y]=dis[x][y]+(i<=2);
                q.push((leo){dis[X][Y],X,Y});
            }
        }
    }
}

int main()
{
    dx[1]=0;dx[2]=0;dx[3]=1;dx[4]=-1;
    dy[1]=1;dy[2]=-1;dy[3]=0;dy[4]=0;
    scanf("%d%d",&n,&m);
    scanf("%d%d",&Sx,&Sy);
    scanf("%d%d",&Sl,&Sr);
    for(int i=1;i<=n;i++) scanf("%s",st[i]+1);
    Dijkstra();
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            if(st[i][j]=='.'){
                int d=(dis[i][j]+Sy-j)/2;
                if(d>Sl) continue;
                if(dis[i][j]-d<=Sr) ans++;
            }
    printf("%d\n",ans);
    return 0;
}

解法2、有个东西叫deque?双端队列,那么根据普通bfs错误的原因,把需要消耗步数的放到后面做,优先做不需要步数的就好了喵?

//Leo
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <deque>
using namespace std;
int n,m,Sx,Sy,X,Y,ans;
int vis[2020][2020];
char st[2020][2020];

struct leo{
    int x,y,s1,s2;
};
deque<leo> q;

int main()
{
    scanf("%d%d",&n,&m);
    scanf("%d%d",&Sx,&Sy);
    scanf("%d%d",&X,&Y);
    for(int i=1;i<=n;i++) scanf("%s",st[i]+1);
    q.push_back((leo){Sx,Sy,X,Y});
    while(!q.empty()){
        leo tmp=q.front();q.pop_front();
        int x=tmp.x,y=tmp.y;
        if(vis[x][y]) continue;
        vis[x][y]=1;ans++;
        if(x-1>0 && st[x-1][y]=='.') q.push_front((leo){x-1,y,tmp.s1,tmp.s2});
        if(x+1<=n && st[x+1][y]=='.') q.push_front((leo){x+1,y,tmp.s1,tmp.s2});
        if(y-1>0 && tmp.s1 && st[x][y-1]=='.') q.push_back((leo){x,y-1,tmp.s1-1,tmp.s2});
        if(y+1<=m && tmp.s2 && st[x][y+1]=='.') q.push_back((leo){x,y+1,tmp.s1,tmp.s2-1});
    }
    printf("%d\n",ans);
    return 0;
}

E Dwarves, Hats and Extrasensory Abilities

交互题…喵…(弱弱
你可以询问n个点的颜色然后要求用一条线把白点和黑点分开来。
这题不是我想出来的…(真的不会做?
当然把所有可以询问的机会都放在一条水平线上(纵坐标相同)
这里就可以用二分来确定位置,假设黑点在左边白点在右边,那么询问到黑点就往右询问,否则往左询问。到最后如果还不能确定的话就询问一次略微高于或者低于标准线的点的颜色就能确定分割线是向上去的还是向下去的。
就好了?(抬起头来

//Leo
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
int n,l,r;

int main()
{
    scanf("%d",&n);
    l=0;r=1e9;
    for(int i=1;i<=min(29,n);i++){
        int mid=(l+r)>>1;
        printf("%d 500000000\n",mid);
        fflush(stdout);
        scanf("\n");
        char st[10000];
        scanf("%s",st+1);
        if(st[1]=='b') l=mid;else r=mid;
    }
    if(n<=29){
        printf("%d 500000001 %d 499999999\n",l,r);
        fflush(stdout);
        return 0;
    }
    printf("%d 600000000\n",l);
    fflush(stdout);
    scanf("\n");
    char st[10000];
    scanf("%s",st+1);
    if(st[1]=='b') printf("%d 499999999 %d 500000001\n",l,r);
    else printf("%d 500000001 %d 499999999\n",l,r);
    fflush(stdout);
    return 0;
}

F题待填qwq(还不会…

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值