1. 程式人生 > >雅禮培訓 1.2

雅禮培訓 1.2

輸入數據 break char str [1] %d ria 給定 lap

模擬賽

串(string)

【題目描述】
給定一個由小寫字母組成的字符串 s,每次你可以刪去它的一個非回文子串,
求刪成空串的最小次數。
【輸入數據】
第一行一個整數 t 表示數據組數。
每組數據第一行一個整數 n 表示字符串長度,第二行一個字符串 s。
【輸出數據】
每組數據輸出一行一個整數表示答案,如果無法刪成空串輸出-1。
【樣例輸入】
2
7
abcdcba
3
xxx
【樣例輸出】
2
-1
【樣例解釋】
對於第一個樣例,一種最優方案為 abcdcba->adcba->空串。
【數據範圍】
對於 30%的數據,n<=10。
對於 60%的數據,n<=100。
對於 100%的數據,t<=20,n<=10^5。

技術分享圖片
#include<iostream>
#include<cstdio>
#include<cstring>
#define maxn 110
#define INF 0x7fffffff
using namespace std;
int ans;
struct node{
    string s;
    int len;
};
void solve(node now,int step){//已經進行了step次 
    if(step>=ans)return;
    for(int l=0;l<now.len;l++){
        
for(int r=l+1;r<now.len;r++){ int ll=l,rr=r;bool flag=0; while(ll<=rr){ if(now.s[ll]!=now.s[rr]){flag=1;break;} else ll++,rr--; } if(flag==0)continue; node nxt;nxt.s="";nxt.len=0; for(int
i=0;i<l;i++)nxt.s+=now.s[i],nxt.len++; for(int i=r+1;i<now.len;i++)nxt.s+=now.s[i],nxt.len++; if(nxt.len==0){ ans=min(ans,step+1); return; } solve(nxt,step+1); } } } int main(){ // freopen("Cola.txt","r",stdin); freopen("string.in","r",stdin);freopen("string.out","w",stdout); int T; scanf("%d",&T); while(T--){ ans=INF; node str; scanf("%d",&str.len);cin>>str.s; solve(str,0); if(ans<INF)printf("%d\n",ans); else puts("-1"); } return 0; }
30分 暴力 技術分享圖片
/*
    首先如果s不是回文串答案為1。
    考慮對於1<=i<n,是否都滿足s[1..i]和s[i+1..n]至少有一個是回文的。如果不滿足那麽答案為2。
    如果滿足的話,如果s[1]=s[2],那麽s只會形如aaaaa或aaabaaa;如果s[1]!=s[2],那麽s只會形如abababa。這三種情況都是無解的。
*/
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
int n;
char s[100010];
int main(){
    freopen("string10.in","r",stdin);
    int T;
    scanf("%d",&T);
    while(T--){
        scanf("%d%s",&n,s+1);
        int l=1,r=n;
        bool flag=0;
        while(l<=r){
            if(s[l]!=s[r]){flag=1;break;}//不是回文串 
            l++,r--;
        }
        if(flag){puts("1");continue;}
        for(int i=1;i<=n;i++){//枚舉中間點 
            l=1,r=i;
            bool flag1=0,flag2=0;
            while(l<=r){
                if(s[l]!=s[r]){flag1=1;break;}
                l++,r--;
            }
            if(flag1==0)continue;
            l=i+1,r=n;
            while(l<=r){
                if(s[l]!=s[r]){flag2=1;break;}
                l++;r--;
            }
            if(flag1&&flag2){flag=1;puts("2");break;}
        }
        if(!flag)puts("-1");
    }
    return 0;
}
60分 結論+暴力判斷是否回文


變量(variable)


【題目描述】
有 n 個變量 w[1]~w[n],每個變量可以取 W 或-W。
有 p 個式子,形如 Hi=ai|w[xi]-w[yi]|+bi|w[yi]-w[zi]|+ci|w[zi]-w[xi]|
+di(w[xi]-w[yi])+ei(w[yi]-w[zi])+fi(w[zi]-w[xi])。
有 q 個條件,形如 w[x]<=w[y]或 w[x]=w[y]或 w[x]<w[y]。
最小化 sigma(wi)+sigma(Hi)。
【輸入數據】
第一行一個整數 t 表示數據組數。
每組數據第一行四個整數 n,W,p,q 表示節點數。
接下來 p 行每行九個整數 xi,yi,zi,ai,bi,ci,di,ei,fi。
接下來 q 行每行三個整數 x,y,r。
r=0 表示 w[x]<=w[y];r=1 表示 w[x]=w[y];r=2 表示 w[x]<w[y]。
保證存在方案。
【輸出數據】
每組數據輸出一行一個整數表示 sigma(wi)+sigma(Hi)的最小值。
【樣例輸入】
1
3 1 1 1
1 2 3 1 1 1 1 1 1
1 2 2
【樣例輸出】
3
【數據範圍】
對於 30%的數據,n<=15,p,q<=20。
對於 100%的數據,t<=10,n<=500,p,q<=1000,1<=W<=10^6,
0<=ai,bi,ci,di,ei,fi<=1000。


取石子(stone)


【題目描述】
有 n 堆石子,第 i 堆有 xi 個。
Alice 和 Bob 輪流取石子(先後手未定),Alice 每次從一堆中取走 a 個,Bob
每次從一堆中取走 b 個,無法操作者輸。
不難發現只會有四種情況:Alice 必勝;Bob 必勝;先手必勝;後手必勝。
你需要選定若幹堆石子(共有 2^n 種方案),Alice 和 Bob 只能在你選出的堆
中取,問以上四種情況對應的方案數。
【輸入數據】
第一行三個整數 n,a,b,第二行 n 個整數 x1~xn。
【輸出數據】
一行四個整數,分別表示 Alice 必勝、Bob 必勝、先手必勝和後手必勝的方
案數,對 10^9+7 取模。
【樣例輸入】
2 2 3
2 3
【樣例輸出】
2 0 1 1
【樣例解釋】
選定空集時後手必勝,選定{2}時 Alice 必勝,選定{3}時先手必勝,選定{2,3}時 Alice
必勝。
【數據範圍】
對於 10%的數據,n,xi<=5。
對於 50%的數據,n<=20。
對於另外 10%的數據,a=b。
對於又另外 20%的數據,a=1。
對於 100%的數據,1<=n<=100000,1<=a,b,xi<=10^9。

雅禮培訓 1.2