1. 程式人生 > 實用技巧 >Codeforces Round #644 (Div. 3) 解題報告

Codeforces Round #644 (Div. 3) 解題報告

Codeforces Round #644 (Div. 3)

A. Minimal Square

思路

#include<bits/stdc++.h>
#define ll long long
#define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
using namespace std;
// 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 a,b;cin>>a>>b;
        if(a>b)swap(a,b);
        int tmp=max(a*2,b);
        cout<<tmp*tmp<<"\n";
    }
    return 0;
}

B. Honest Coach

思路

排序後取最小間隔

#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[100];
// 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];
       sort(a+1,a+1+n);
       int minn=1e8;
       for(int i=2;i<=n;i++)minn=min(minn,a[i]-a[i-1]);
       cout<<minn<<"\n"; 
    }
    return 0;
}

C. Similar Pairs

思路

分類討論,分別記錄奇數和偶數的個數,若兩者個數的奇偶性不相等則直接輸出NO,兩者個數都為偶數直接輸出YES,兩者個數都為奇數則排序後跑一遍陣列尋找有無相鄰的數(差為1),只要能找到一對則可用題中另一種配對操作將其轉化為兩者個數都為偶數的情況,輸出YES;一對都找不到則輸出NO。

#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[60];
// 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;
        int cnt1=0,cnt2=0;
        for(int i=1;i<=n;i++)
        {
            cin>>a[i];
            a[i]%2==0?cnt1++:cnt2++;
        }
        sort(a+1,a+1+n);
        if(cnt1%2==0&&cnt2%2==0){cout<<"YES\n";continue;}
        else if(cnt1%2!=cnt2%2){cout<<"NO\n";continue;}
        int f=0;
        for(int i=2;i<=n;i++)
            if(a[i]-a[i-1]==1){f=1;break;}
        if(f)cout<<"YES\n";
        else cout<<"NO\n";
    }
    return 0;
}

D. Buying Shovels

思路

題意就是給出一個n,讓你找出n在1~k中最大的因數。一開始我看資料範圍好像不太能暴力寫了個素數篩來分解,WA了一發之後發現素數篩只能處理素數因子,於是敲了暴力就過了。。。(其實就是沒好好分析複雜度)

#include<bits/stdc++.h>
#define ll long long
#define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
using namespace std;
// 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;
    //cout<<"gg";
    int t;cin>>t;
    while(t--)
    {
        int n,k;cin>>n>>k;
        if(n<=k){cout<<"1\n";continue;}
        int ans=n;
        for(int i=2;i<=k&&i*i<=n;i++)
        {
            if(n%i==0)
            {
                if(n/i<=k){ans=i;break;}
                ans=n/i;
            }
        }
        cout<<ans<<"\n";
    }
    return 0;
}

E. Polygon

思路

讀完題之後觀察一會,發現所有的1要麼靠著最右邊或者最下邊,要麼右邊或者下邊有另一個1,然後跑一遍圖對所有1判這個條件就行了。

#include<bits/stdc++.h>
#define ll long long
#define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
using namespace std;
// 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;
// }
char s[60][60];
int main()
{
	//freopen(".in","r",stdin);
	//freopen(".out","w",stdout);
	IO;
	int t;cin>>t;
	while(t--)
	{
		int n,f=0;cin>>n;
		for(int i=0;i<n;i++)cin>>s[i];
		for(int i=0;i<n;i++)
			for(int j=0;j<n;j++)
				if(s[i][j]=='1')
				{
					if(i==n-1||j==n-1)continue;
					if(s[i+1][j]=='1'||s[i][j+1]=='1')continue;
					f=1;
				}
		if(f)cout<<"NO\n";
		else cout<<"YES\n";
	}
    return 0;
}

F. Spy-string

思路

看了一眼資料範圍果斷怎麼暴力怎麼來,於是就取了第一串當板子,然後列舉,每一位改成a~z之後與所有串比對能否滿足條件,穩過。

#include<bits/stdc++.h>
#define ll long long
#define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
using namespace std;
// 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;
// }
char s[60][60];
char ss[60],ans[60];
int n,m;
bool finddiffer()
{
    int ff=0;
    for(int i=1;i<=n;i++)
    {
        int cnt=0;
        for(int j=0;j<m;j++)
            if(s[i][j]!=ss[j])cnt++;
        if(cnt>1){ff=1;break;}
    }
    if(ff)return false;
    return true;
}
int main()
{
	//freopen(".in","r",stdin);
	//freopen(".out","w",stdout);
	IO;
    int t;cin>>t;
    while(t--)
    {
        memset(ss,0,sizeof(ss));
        int f=0;cin>>n>>m;
        for(int i=1;i<=n;i++)cin>>s[i];
        for(int i=0;i<m;i++)ss[i]=s[1][i];
        //cout<<ss<<'\n';
        if(finddiffer()){cout<<ss<<"\n";continue;}
        for(int i=0;i<m;i++)
        {
            char tmp=ss[i];
            for(int j=0;j<26;j++)
            {
                ss[i]=char(j+'a');
                if(finddiffer()){f=1;break;}
            }    
            if(f)break;
            ss[i]=tmp;
        }
        if(f)cout<<ss<<"\n";
        else cout<<"-1\n";
    }
    return 0;
}

G. A/B Matrix

思路

一開始想簡單了直接無腦放,不出意外WA2,仔細想了想發現是一個類似於輪換串的東西。首先1的總數算兩次要滿足條件,所以an=bm必須要滿足,否則直接輸出NO,然後就是需要進行挪動操作,可以對著下面這個例子看:

1  
17 17 13 13  
YES  
11111111111110000  
01111111111111000  
00111111111111100  
00011111111111110  
00001111111111111  
10000111111111111  
11000011111111111  
11100001111111111  
11110000111111111  
11111000011111111  
11111100001111111  
11111110000111111  
11111111000011111  
11111111100001111  
11111111110000111  
11111111111000011  
11111111111100001  

這樣看下來就有點輪換那味了,n個位移,剛好到第m列的時候是一個輪迴。假設位移為dis,(dis*n)%m==0。從小到大列舉,求dis。
(此處有參考知乎ZqIceberg大神的題解,傳送門)

#include<bits/stdc++.h>
#define ll long long
#define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
using namespace std;
// 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 g[60][60];
int main()
{
	//freopen(".in","r",stdin);
	//freopen(".out","w",stdout);
	IO;
    int t;cin>>t;
    while(t--)
    {
        memset(g,0,sizeof(g));
        int n,m,a,b;cin>>n>>m>>a>>b;
        if(a*n!=b*m){cout<<"NO\n";continue;}
        int dis=1;
        while(dis*n%m!=0)dis++;
        //cout<<"dis="<<dis<<"\n";
        for(int i=0,del=0;i<n;i++,del+=dis)
            for(int j=0;j<a;j++)
                g[i][(j+del)%m]=1;
        cout<<"YES\n";
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<m;j++)
                cout<<g[i][j];
            cout<<"\n";
        }
    }
    return 0;
}

H. Binary Median

待補。^_^