Codeforces Round #656 (Div. 3)A,B,C,D,E(其他待补)

  1. A. Three Pairwise Maximums

简单题,但是我想了蛮久的,我哭了。对于满足条件的x,y,z绝对有两个数是相等的而且还要大于另外一个数,我也不好解释为什么,所以,,,,将就一下吧,自己看看样例想想吧,面向答案编程我太难了。
我不是很想写题意,因为本来就是容易理解的英文题,而且出去打比赛都是英文题,大家要习惯看英文

void sove()
{
    int a[4];
    scanf("%d%d%d",&a[1],&a[2],&a[3]);
    sort(a+1,a+1+3);
    if(a[3]==a[2]&&a[3]>=a[1])
    {
        printf("YES\n");
        printf("%d %d %d\n",a[1],a[1],a[3]);
    }
    else
    {
        printf("NO\n");
    }
}

2.B. Restore the Permutation by Merger
这才是签到题该有的样子,题意就不说了,很好理解做法就是从左到右标记数,如果没出现过就输出,并且标记,出现过就直接跳过

void sove()
{
    int n;
    scanf("%d",&n);
    for(int i=1;i<=2*n;i++)
    {
        scanf("%d",&a[i]);
    }
    ms(vis,0);
    for(int i=1;i<=2*n;i++)
    {
        if(!vis[a[i]])
        {
            printf("%d ",a[i]);
            vis[a[i]]=1;
        }
    }
    printf("\n");
}

3.C. Make It Good
c题就别人都是模拟过的,我特么用了二分才过,气死我了,这个题肯定满足二分,因为删的越多数,那么越可能是对的,删的越少越不可能是对的。

bool check(int x)
{
    int l=x+1,r=n,ma=0;
    bool flage=true;
    while(r>=l)
    {
        if(a[l]>=a[r]&&ma<=a[r])
        {
            ma=a[r];
            r--;
        }
        else if(a[l]<a[r]&&a[l]>=ma)
        {
            ma=a[l];
            l++;
        }
        else
        {
            flage=false;
            break;
        }
    }
    return flage;
}
void sove()
{
    //int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&a[i]);
    }
    int l=0,r=n-1,ans;
    while(r>=l)
    {
        int mid=(l+r)>>1;
        if(check(mid))
        {
            r=mid-1;
            ans=mid;
        }
        else
        {
            l=mid+1;
        }
    }
    printf("%d\n",ans);
}

4.D. a-Good String
这个题暴力bfs就可以过,没啥好说的,代码里写点东西应该就知道了

#include<iostream>
#include<stdio.h>
#include<math.h>
#include<string.h>
#include<string>
#include<vector>
#include<queue>
#include<algorithm>
#include<deque>
#include<map>
#include<stdlib.h>
#include<set>
#include<iomanip>
#include<stack>
#define ll long long
#define ms(a,b) memset(a,b,sizeof(a))
#define lowbit(x) x & -x
#define fi first
#define se second
#define bug cout<<"----acac----"<<endl
#define IOS ios::sync_with_stdio(false), cin.tie(0),cout.tie(0)
using namespace std;
const int maxn = 2e5 + 50;
const int maxm = 1.5e5+50;
const double eps = 1e-7;
const int inf = 0x3f3f3f3f;
const ll  lnf  = 0x3f3f3f3f3f3f3f3f;
const int mod = 1e8;
const  double pi=3.141592653589;
char s[maxn],dp[30];
int dfs(int l,int r,char ch)
{
    //if(dp[num])return dp[num];
    if(l==r)特判一下l==r不然会死循环
    {
        return ch==s[l]?0:1;
    }
    int cnt1=0,ans=0,cnt2=0;
    for(int i=l;i<=(l+r)/2;i++)
    {
        if(ch!=s[i])//表示前面一半与ch是否匹配,不匹配就让cnt1++,cnt1表示需要操作的次数
        {
            cnt1++;
        }
    }
    for(int i=(l+r)/2+1;i<=r;i++)
    {
        if(ch!=s[i])//表示后面一半与ch是否匹配,
        {
            cnt2++;
        }
    }
    return min(dfs(l,(l+r)/2,ch+1)+cnt2,dfs((l+r)/2+1,r,ch+1)+cnt1);//注意cnt1与cnt2的位置啊ch+1,列如ch='b',那么ch+1='c'
}
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        int n;
        ms(dp,0);
        cin>>n>>s+1;
        printf("%d\n",dfs(1,n,'a'));
    }
    return 0;
}

E. Directing Edges
昨天打完比赛才看拓扑排序,今天看别人题解就是用拓扑排序,真的就这么巧吗????

#include<iostream>
#include<stdio.h>
#include<math.h>
#include<string.h>
#include<string>
#include<vector>
#include<queue>
#include<algorithm>
#include<deque>
#include<map>
#include<stdlib.h>
#include<set>
#include<iomanip>
#include<stack>
#define ll long long
#define ms(a,b) memset(a,b,sizeof(a))
#define lowbit(x) x & -x
#define fi first
#define se second
#define bug cout<<"----acac----"<<endl
#define IOS ios::sync_with_stdio(false), cin.tie(0),cout.tie(0)
using namespace std;
const int maxn = 2e5 + 50;
const int maxm = 1.5e5+50;
const double eps = 1e-7;
const int inf = 0x3f3f3f3f;
const ll  lnf  = 0x3f3f3f3f3f3f3f3f;
const int mod = 1e8;
const  double pi=3.141592653589;
vector<int>ve[maxn];
int in[maxn],n,pxun[maxn];
bool toop_sort()//拓扑排序板子
{
    queue<int>q;
    for(int i=1;i<=n;i++)
    {
        if(!in[i])
        {
            q.push(i);
        }
    }
    int ans=0;
    while(!q.empty())
    {
        int u=q.front();
        q.pop();
        pxun[u]=ans++;//记录拓扑序
        for(int i=0;i<ve[u].size();i++)
        {
            int v=ve[u][i];
            in[v]--;
            if(!in[v])
            {
                q.push(v);
            }
        }
    }
    return ans==n;
}
int vis[maxn],din[maxn],dout[maxn];
void sove()
{
    int m;
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
    {
        ve[i].clear();
        in[i]=0;
    }
    for(int i=1;i<=m;i++)
    {
        scanf("%d%d%d",&vis[i],&din[i],&dout[i]);
        if(vis[i])
        {
            ve[din[i]].push_back(dout[i]);
            in[dout[i]]++;
        }
    }
    if(toop_sort())
    {
        printf("YES\n");
    }
    else
    {
        printf("NO\n");
        return;
    }
    for(int i=1;i<=m;i++)
    {
        if(vis[i]||pxun[din[i]]<pxun[dout[i]])//学了拓扑排序的应该知道拓扑序小的一定是不会被拓扑序大的指到;
        {
            printf("%d %d\n",din[i],dout[i]);
        }
        else
        {
            printf("%d %d\n",dout[i],din[i]);
        }
    }
}
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        sove();
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qcccc_/article/details/107424166