1. 程式人生 > >第八屆ACM趣味程式設計競賽第三場(正式賽)官方題解

第八屆ACM趣味程式設計競賽第三場(正式賽)官方題解

Source:LinPC

題解:首先預處理統計a-z字元的數量,根據漸變字串的定義,由於總字元數較小,所以可以列舉漸變字串的起點,然後找到由該起點起始的最大漸變字串,然後從統計的字元中刪除所用字元,如此迴圈操作至剩餘字元數為0即可

題解: 易得,只要最長的那條邊的長度大於其它的邊,那麼就可以圍成一個多邊形,所以只需要維護當前的i條邊中最長的那條邊長度和其它邊的長度和就好了

Little_Pro(小pro) 是 ProLights 的小號,哈哈

Source:ProLights

題解:貪心、字串處理
對於 1010101...... (0 ~ n-1) 如果奇數的地方不是1就 ans1++, 如果偶數的地方不是0就 ans0++,
ans = max(ans0, ans1); //min(ans0, ans1)次交換, ans - min(ans0, ans1) 次改變司機的好壞
然後再對 010101......(0 ~ n-1) 的情況跑一遍
2個ans取最小值
複雜度 O(n)

Source:CS_LYJ1997

題解:根據題目所述規則,zhong_wang手上會有1-2張牌,而cfeitong手上會有1-13張牌。如果zhong_wang手上只有一張牌,則zhong_wang必勝;
如果zhong_wang手上有兩張牌,則zhong_wang會先比較自己手上較大的牌和cfeitong手上最大的牌,
如果zhong_wang手上較大的牌cfeitong壓不起,則zhong_wang先出較大的牌,再出較小的牌,zhong_wang獲勝;
如果zhong_wang發現cfeitong能壓住zhong_wang手中較大的那張牌,則zhong_wang先出手中較小的那張牌,留下較大的那張牌。
因為cfeitong能壓得起zhong_wang手上較大的牌,必然能壓起zhong_wang出的這張較小的牌,因為zhong_wang手上只剩下一張牌了,
則cfeitong肯定從大的往小的出,因此判斷cfeitong手上是否有兩張牌比zhong_wang剩下的那張牌小,如果存在則zhong_wang勝,不存在則cfeitong勝。
資料生成說明:
test01-02為樣例
test03-09為手工製造資料
test10-39為電腦隨機資料

資料丟在新生群裡了
建議時間限制:3000/1000MS(Java/Others)
建議記憶體限制:65535/65535KB(Java/Others)

Source:鍾大爺 zhong_wang

題解:解題報告
分類討論
存在較多情況,比如a,b,c某個數為0等等,需要很細心的討論
這裡介紹a>1,b>1,c>1時的情況
此時,對於任意x<=6,顯然可以構造
對於x>6,如果x=a+2*b+3*c,顯然可以構造,否則,必然還有若干個a,b,c沒有使用,如剩餘一個a,則可以通過x-a+a構造出x
所以對於1到a+2*b+3*c的所有整數均可以構造
原題是BNUOJ的52297,網上有很多不同的思路可供參考
資料生成說明
精心構造的毒瘤資料
建議設定的時間限制,記憶體限制
1000ms,65535KB

標程

A-AC程式碼中的一份

#include<stdio.h>
#include<string.h>
int main()
{
	int n,q=0,f[30]={0};
	char  a[1002];
	scanf("%d",&n);
	scanf("%s",a);
	for (int i=0;i<n;i++)
    {
			int k;
			k=a[i]-'a'+1;
			f[k]++;
    }
    while (n!=0)
    {
        int i=1;
        while (f[i]==0) i++;
        int m=i;
        while(f[m]!=0){
            f[m]--;
            m++;
        }
        q++;
        n=n-(m-i);
    }
    printf("%d\n",q);
	return 0;
}

B-標程

#include <iostream>
#include<cstdio>
using namespace std;

int a[1000005];

int main()
{
    int n,i,m;
    int s;
    scanf("%d",&n);
    for(i = 0; i < n; i++) scanf("%d",&a[i]);
    if(n < 3) {printf("-1\n"); return 0;}
    m = max(a[0],a[1]);
    s = min(a[0],a[1]);
    for(i = 2; i < n; i++)
    {
        if(a[i] > m)
        {
            s += m;
            m = a[i];
        }
        else s += a[i];
        if(s > m) break;
    }
    if(i < n) printf("%d\n",i + 1);
    else printf("-1\n");
    return 0;
}


C-標程

#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
using namespace std;
typedef long long LL;
const int maxn = 1e5 + 8;

bool v[maxn];

int main()
{
    #ifdef LOCAL
    freopen("36.in", "r", stdin);
    freopen("36.out", "w", stdout);
    int T = 1;
    while(T--){
    #endif // LOCAL
    ios::sync_with_stdio(false); cin.tie(0);

    string s, s1, s2;
    LL n, ans0 = 0, ans1 = 0, ans = 0;
    cin >> n;
    cin >> s;
    s1 = s;
    s2 = s;
    for(int i = 0; i < n; i++){
        if(s[i] == '0'){
            v[i] = 0;
            v[i] = 0;
        }
        else{
            v[i] = 1;
            v[i] = 1;
        }
    }

    for(int i = 0; i < n; i++){
        //cout << v[i] <<" ";
        if(i % 2 == 0){
            if(v[i] == 0) ;
            else ans0++;
        }
        else{
            if(v[i] == 1) ;
            else ans1++;
        }
    }
    //cout << endl;
    //cout <<ans0 << " " << ans1 << endl;
    ans = max(ans0, ans1);

    ans0 = ans1 = 0;
    for(int i = 0; i < n; i++){
        //cout << v[i] <<" ";
        if(i % 2 == 0){
            if(v[i] == 1) ;
            else ans0++;
        }
        else{
            if(v[i] == 0) ;
            else ans1++;
        }
    }
    //cout <<ans0 << " " << ans1 << endl;

    ans = min(ans, max(ans0, ans1));

    cout << ans << endl;


    #ifdef LOCAL
    //cout << endl;
    }
    #endif // LOCAL
    return 0;
}


D-標程

#include<stdio.h>
#include<string.h>
int convert(char c)
{
    if (c>='3' && c<='9') return c-48;
    if (c=='T') return 10;
    if (c=='J') return 11;
    if (c=='Q') return 12;
    if (c=='K') return 13;
    if (c=='A') return 14;
    return 15;
}
int main()
{
    int len1,len2,c1max,c2max,ans,cnt,i;
    char s1[5],s2[20];
    scanf("%s",s1);
    scanf("%s",s2);
    len1=strlen(s1);len2=strlen(s2);
    if (len1==1) ans=1;
    else
    {
        c1max=convert(s1[len1-1]);
        c2max=convert(s2[len2-1]);
        if (c1max>=c2max) ans=1;
        else
        {
            cnt=0;
            for(i=0;i<len2;i++)
                if (convert(s2[i])<c1max) cnt++;
            if (cnt>=2) ans=1;
            else ans=0;
        }
    }
    if (ans) printf("zhong_wang\n");
    else printf("cfeitong\n");
    return 0;
}


E-標程

#include<bits/stdc++.h>

#define clr(x,y) memset((x),(y),sizeof(x))
using namespace std;

int a,b,c;

int main(void)
{
    scanf("%d%d%d",&a,&b,&c);

    int ans=0;
    if (a==0 || b==0 || c==0)
    {
        if (a==0 && b==0 && c==0)
        {
            ans=0;
        }
        else if ((a==0 && b==0) || (a==0 && c==0) || (b==0 && c==0))
        {
            ans=a+b+c;
        }
        else
        {
            if (a==0)
            {
                if (b>1 && c>1)
                {
                    ans=2*b+3*c-2;
                }
                else if (b>1 && c==1)
                {
                    ans=2*b+1;
                }
                else if (c>1 && b==1)
                {
                    ans=2*c+1;
                }
                else ans=3;
            }
            else if (b==0)
            {
                if (a>1 && c>1)
                {
                    ans=a+3*c;
                }
                else if (a>1 && c==1)
                {
                    ans=a+3*c;
                }
                else if (a==1 && c>1)
                {
                    ans=2*c+1;
                }
                else ans=3;
            }
            else
            {
                ans=a+2*b;
            }
        }
    }
    else
    {
        ans=a+2*b+3*c;
    }
    printf("%d\n",ans);
}


  Thank you!