雅礼培训 1.2

Posted Soda

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了雅礼培训 1.2相关的知识,希望对你有一定的参考价值。

模拟赛

串(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的主要内容,如果未能解决你的问题,请参考以下文章

雅礼培训day1 世界线 Worldline

湖南雅礼培训 1.4

湖南雅礼培训 1.1

雅礼集训1.2 T3取石子

雅礼集训1.2 T1串

JavaScript单行代码,也就是代码片段