(CF)Educational Codeforces Round 49

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_37868325/article/details/81840199

红红火火恍恍惚惚,哈哈哈哈上分喽,上了60整o(* ̄▽ ̄*)ブ,蓝蓝的~

话说昨晚打的也并不十分顺利,CD都WA了好几发QAQ索性没挂终测不然真是凉了~

A、Palindromic Twist

http://codeforces.com/contest/1027/problem/A

题意:一串字符串,每个字符都必须上或下移动一个位子,AZ只有一种移动方法。求能否构成回文串

思路:大水题,前后对称位置ASCLL值均差2或0,有一个不符合的就不可以,看了几个被hack的代码,有的是考虑了az可以互换。。但实际不可以

代码:

#include<bits/stdc++.h>
using namespace std;
char ch[105];
int T,n,ok,l;
int main()
{
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&n);
        ok=1;
        scanf("%s",ch);
        for(int i=0;i<n/2;i++)
        {
            l=ch[i]-ch[n-1-i];
            if(l<0) l=-l;
            if(l==2||l==0) continue;
            else {ok=0;break;}
        }
        if(ok) printf("YES\n");
        else printf("NO\n");
    }
}

B:Numbers on the Chessboard

http://codeforces.com/contest/1027/problem/B

题意:n*n的矩阵,从上往下,从左到右先将行列坐标为偶数的格子依次填上数,再将剩下的填上数、q次询问[x,y]格内的数字

思路:这个我是粉丝种情况讨论的,但是赛后看了别人的代码,,自己还是想错 了,将格子依次编号,就可以看出,和为偶数与奇数的相邻,所以可以直接考虑第((x-1)*n+y)个格子,,代码一看就懂。。是自己傻了,白白浪费了时间

大佬代码:

#include<iostream>
using namespace std;
typedef long long ll;
ll n,q,a,b,ans;
int main(){
	cin>>n>>q;
	while(q--){
		cin>>a>>b;
		ans=(a-1)*n+b+1;
		if((a+b)%2)ans+=n*n;
		cout<<ans/2<<endl;
	}
}

自己的麻烦代码:

#include<bits/stdc++.h>
using namespace std;
const int mod=998244353;
long long n,q,x,y,ans;
int main()
{
	scanf("%lld%lld",&n,&q);
	while(q--)
    {
        scanf("%lld%lld",&x,&y);
        if(n%2==0)
        {
            if((x+y)%2==0)
            {
                ans=(x-1)/2*n;
                if(x%2==0) ans+=n/2+y/2;
                else ans+=y/2+y%2;//cout<<x<<" "<<y<<" "<<ans<<endl;

            }
            else
            {
                ans=n*n/2+(x-1)/2*n;
                if(x%2==0) ans+=n/2+y/2+y%2;
                else ans+=y/2;
            }
        }
        else
        {
            if((x+y)%2==0)
            {
                ans=(x-1)/2*n;
                if(x%2==0) ans+=n/2+1+y/2;
                else ans+=y/2+y%2;
            }
            else
            {
                ans=n*n/2+1+(x-1)/2*n;
                if(x%2==0) ans+=n/2+y/2+y%2;
                else ans+=y/2;
            }
        }
        printf("%lld\n",ans);

    }
}

C、 Minimum Value Rectangle

http://codeforces.com/contest/1027/problem/C

题意:给出n根木棍的长度,求从中选择4根,能组成最小的(周长的平方/面积)的值的4根的长度

思路:带入长宽化简,就可以得出是要求(a/b+b/a)的最小值,就是将长度数量多于两根的取出来,加入set,然后依次往外取,相邻两根比较队化简后的对应值一直更新最小值即可。

不过这个题真的有毒,,一开始多加了一个break,导致输入没输完导致WA,,然后又因为memset  TLE了。。。1e4的数组开成了1e5的,不然比赛的时候不会T,,但是会挂终测。。。幸好当时开大了,,不然真的要挂,,真是幸运~~取消memset就是记录一下n个数,最后重置一下就可以

代码:

#include<bits/stdc++.h>
using namespace std;
const int mod=998244353;
int T,n,num[10005],x,y,ans[5],ok,a[1000005];
int main()
{
    set<int>q;
	scanf("%d",&T);
	while(T--)
    {
        ok=0;
        q.clear();
        //memset(num,0,sizeof(num));
        scanf("%d",&n);
        ans[0]=-1;
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
            x=a[i];
            num[x]++;
            if(num[x]==2) q.insert(x);
            if(num[x]==4) {ans[0]=x;ans[1]=x;ok=1;}
        }
        for(int i=1;i<=n;i++) num[a[i]]=0;
        if(ans[0]!=-1)
        {
            printf("%d %d %d %d\n",ans[0],ans[0],ans[1],ans[1]);
        }
        else
        {
            x=*q.begin();
            q.erase(q.begin());
            double pp=10000000000.0;
            while(!q.empty())
            {
                y=*q.begin();
                q.erase(q.begin());
                if(4*(x*(1.0)/y)+4*(y*(1.0)/x)+8<pp)
                {
                    pp=4*(x*(1.0)/y)+4*(y*(1.0)/x)+8;
                   // cout<<pp<<endl;
                    ans[0]=x;
                    ans[1]=y;
                }
                x=y;
            }
            printf("%d %d %d %d\n",ans[0],ans[0],ans[1],ans[1]);
        }
    }
}

D、Mouse Hunt

http://codeforces.com/contest/1027/problem/D

题意:n个房间,一只老鼠,老鼠到达房间i,下一次会到达房间a【i】,若a[i]==i,老鼠原地不动,在每个房间放捕鼠器都会花费对应价值,求使老鼠不论从何房间进入都能被抓到的最小花费

思路:这个有点像那场多校狼人杀的那个游戏的那个题,(题解)都是每个点出度只有1,这个题只需要再每条边的终点放捕鼠器就可以,有环的话就要选环上最小的一个房间,再就是要注意由边进环的情况,例如1->2->3->4->5->3.就是处理略微麻烦,,但是不难,,就是又傻了,,忘记判断最后纯环的情况,白WA了三发。。。心痛

代码:

#include<bits/stdc++.h>
using namespace std;
const int MAX=2e5+5;
int T,n,c[MAX],fa[MAX],num,in[MAX],out[MAX],look[MAX],ss[MAX];
long long ans;
void PP(int rt,int ff,int ok,int minn)
{
    //zz[rt]=1;
    look[rt]=1;
    if(ok&&rt==ff) {ans+=minn;return;}
    PP(fa[rt],ff,1,min(minn,c[rt]));
}
void dfs(int rt,int id)
{
    //cout<<rt<<endl;
    if(ss[rt]!=0&&ss[rt]!=id&&look[rt]) return;
    ss[rt]=id;
    //if(zz[rt]) return;
    if(look[rt]) {PP(rt,rt,0,0x3f3f3f3f);return;}
    look[rt]=1;
    if(fa[rt]==rt) {ans+=c[rt];return;}
    dfs(fa[rt],id);
}
int main()
{
    scanf("%d",&n);
    ans=0;
    for(int i=1;i<=n;i++)
        scanf("%d",&c[i]);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&fa[i]);
        if(fa[i]==i) {continue;}
        in[fa[i]]++;
    }
    for(int i=1;i<=n;i++)
    {
        if(in[i]==0) dfs(i,i);
    }
    for(int i=1;i<=n;i++)
    {
        if(look[i]==0) PP(i,i,0,0x3f3f3f3f);
    }
    printf("%lld\n",ans);
}

猜你喜欢

转载自blog.csdn.net/qq_37868325/article/details/81840199