1. 程式人生 > 實用技巧 >Codeforces Round #656 (Div.3) 部分題解

Codeforces Round #656 (Div.3) 部分題解

Codeforces Round #656 (Div. 3)

A. Three Pairwise Maximums

思路

分類討論,x、y、z三個數有兩個數相等且另一個數小於等於這兩個數就能找到合法的a、b、c,具體直接看程式碼吧。(水題練下python)

T=int(input())
for i in range(T):
    x,y,z=map(int,input().split())
    if x==y:
        if z>x:
            print("NO")
            continue
        else:
            print("YES")
            print(x,z,1)
    elif x==z:
        if y>x:
            print("NO")
            continue
        else:
            print("YES")
            print(y,x,1)
    elif y==z:
        if x>y:
            print("NO")
            continue
        else:
            print("YES")
            print(1,x,z)
    else:print("NO")

B. Restore the Permutation by Merger

思路

簡單貪心,每次碰到不同的數直接輸出或者記錄下來最後輸出都ok。

T=int(input())
for tt in range(T):
    hh=[]
    vis=[0]*200
    ans=[]
    n=int(input())
    hh=list(map(int,input().split()))
    for i in hh:
        if vis[i]==0:
            ans.append(i)
            vis[i]=1
    for i in ans:
        print(i,end=' ')

C. Make It Good

思路

因為只能刪字首,所以很容易想到從後往前找一個倒序先增後減序列,碰到“谷”直接記錄序號退出迴圈輸出就好了。

#include<bits/stdc++.h>
#define ll long long
#define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
using namespace std;
int a[200050];
// inline int read()
// {
//     int x=0,f=1;char ch=getchar();
//     while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
//     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
//     return x*f;
// }
int main()
{
	//freopen(".in","r",stdin);
	//freopen(".out","w",stdout);
	IO;
    int t;cin>>t;
    while(t--)
    {
        int n;cin>>n;
        for(int i=1;i<=n;i++)cin>>a[i];
        int f=0,ans=0;
        for(int i=n-1;i>=1;i--)
        {
            if(!f)
            {
                if(a[i]<a[i+1])f=1;
            }
            else 
            {
                if(a[i]>a[i+1]){ans=i;break;}
            }
        }
        cout<<ans<<"\n";
    }
    return 0;
}

D. a-Good String

思路

讀完題發現很明顯的分治,n是2的17次方,寫個遞迴暴力就能過。

#include<bits/stdc++.h>
#define ll long long
#define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
using namespace std;
char s[132000];
// inline int read()
// {
//     int x=0,f=1;char ch=getchar();
//     while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
//     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
//     return x*f;
// }
int solve(int l,int r,char ch)
{
    if(l==r)return s[l]!=ch;
    int mid=l+r>>1;
    int cntl=0,cntr=0;
    for(int i=l;i<=mid;i++)if(s[i]!=ch)cntl++;
    for(int i=mid+1;i<=r;i++)if(s[i]!=ch)cntr++;
    int ans1=solve(mid+1,r,ch+1),ans2=solve(l,mid,ch+1);
    return min(ans1+cntl,ans2+cntr);
}
int main()
{
	//freopen(".in","r",stdin);
	//freopen(".out","w",stdout);
	IO;
    int t;cin>>t;
    while(t--)
    {
        int n;cin>>n;
        cin>>s+1;
        cout<<solve(1,n,'a')<<'\n';
    }
    return 0;
}

E. Directing Edges

思路

感覺是道好題,有向無向邊需要分開處理,拓撲排序來避免環的出現也很妙。首先對所有的有向邊建圖判環,有環直接輸出NO,無環則剩下的邊可以按照拓撲序從小到大連邊,拓撲序就按編號從小到大連邊。根據拓撲排序的原理,一個點在訪問過後不會再被訪問,可以完美避免環的出現。
此處有參考suxxsfe的題解,傳送門

#include<bits/stdc++.h>
#define ll long long
#define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
using namespace std;
const int maxn=2e5+50;
int Head[maxn],V[maxn*2],Nxt[maxn*2],du[maxn],vis[maxn],crcl[maxn],step[maxn];
int tot,cnt,cntt,cnttt;
int n,m;
pair<int,int>e[maxn],ee[maxn];
void Add(int u,int v){V[++tot]=v;Nxt[tot]=Head[u];Head[u]=tot;}
int dfs(int u)
{
    vis[u]=crcl[u]=1;
    for(int i=Head[u];i;i=Nxt[i])
    {
        int v=V[i];
        if(crcl[v])return 1;
        if(!vis[v])
        {
            int tmp=dfs(v);
            if(tmp)return 1;
        }
    }
    crcl[u]=0;
    return 0;
}
void topsort(){
    queue<int>p,q;
    int i,u,v;
    for(i=1;i<=n;i++)if(!du[i])q.push(i);
    while(!q.empty()){
        cnt++;
        while(!q.empty())
        {
            u=q.front();q.pop();
            step[u]=cnt;
            for(i=Head[u];i;i=Nxt[i])
            {
                v=V[i];
                du[v]--;
                if(!du[v])p.push(v);
            }    
        }
    swap(p,q);
    }
}
int main()
{
	//freopen(".in","r",stdin);
	//freopen(".out","w",stdout);
	IO;
    int t;cin>>t;
    while(t--)
    {
        cin>>n>>m;
        for(int i=1;i<=m;i++)
        {
            int type,u,v;
            cin>>type>>u>>v;
            if(type)
            {
                Add(u,v);du[v]++;
                ee[++cnttt].first=u;ee[cnttt].second=v;
            }
            else e[++cntt].first=u,e[cntt].second=v;
        }
        int f=0;
        for(int i=1;i<=n;i++)
            if(!vis[i])
            {
                int tmp=dfs(i);
                if(tmp){f=1;break;}
            }
        if(f){cout<<"NO\n";}
        else
        {
            topsort();
            cout<<"YES\n";
            for(int i=1;i<=cnttt;i++)
                cout<<ee[i].first<<" "<<ee[i].second<<"\n";
            for(int i=1;i<=cntt;i++)
                if(step[e[i].first]<step[e[i].second]||(step[e[i].first]==step[e[i].second]&&e[i].first<e[i].second))cout<<e[i].first<<" "<<e[i].second<<"\n";
                else cout<<e[i].second<<" "<<e[i].first<<"\n";
        }
        for(int i=1;i<=n;i++)Head[i]=vis[i]=crcl[i]=du[i]=0;
	    tot=cnt=cntt=cnttt=0;
    }
    return 0;
}

F. Removing Leaves

思路

明天補

G. Columns Swaps

思路

明天補