1.手工(handicraft)
【题目描述】
小 D 对于手工有一种独特的热情。这一天他得到了一个凸 n 边
形, 每次他可以沿着 任意一条 直线, 将 一块多边形用鱼片劈成两部分。
为了装饰鱼片,他需要得到至少 p 个 m 边形。但是小 D 又很吝惜自
己的鱼片的耐久度,所以他希望用最少的 次数来完成这项工作。
【输入数据】
输入第一行一个正整数 T,表示数据组数。
接下来 T 行,每行三个正整数 n,m,p,意义如题干中所述相同。
【输出数据】
输出 T 行,每行一个整数,表示最少需要劈几次才能完成工作。
【样例输入】
1
8 4 3
【样例输出】
2
【数据范围】
对于 10%的数据,p=1;
对于 40%的数据,p<=10;
另外 20%的数据,m=3;
对于 100%的数据,1<=T<=5,3<=n,m<=10^9,1<=p<=10^9。

暂时不会做,先贴题解:

纺织(textile)
【题目描述】
机户出资,机工出力,这是种花家早期资本主义萌芽的出现。
小 C 有 n 个机工, 小 C 可以安排他们分成若干个组来进行纺织。
当然,如果一个组的人数越多,那么分配给这个组的任务的难度也就
越大。具体来说,就是如果一个组里有 x 个人,那么分配给他们的任
务需要他们用 x 天来完成。为了赚取更多资本,小 C 给机工们下了
一条命令,一组机工完成当前任务后,如果发现其他机工中 只要还有
一组正在工作,那么这组机工必须 立刻 再次开始他们的任务,否则他
们就可以休息了。 所有机工最初都是同时开始工作的, 从他们同时开
始工作的那一刻到所有人都休息的那一刻称为总工作时间。小 C 发
现,分组的情况不同,总工作时间也会有所不同,他想知道,最多可
以产生多少种不同的总工作时间?
【输入数据】
输入只有一行一个正整数 n,表示机工的人数。
【输出数据】
输出一个整数,表示不同的总工作时间数。
【样例输入】
3
【样例输出】
3
【数据范围】
对于 10%的数据,n<=10;
对于 30%的数据,n<=100;
对于 50%的数据,n<=300;
对于 100%的数据,n<=1000。
【样例解释】
有 3 种本质不同的分组方式:
① 分 3 组,每组 1 人,总工作时间为 1。
② 分 2 组,一组 1 人,另一组 2 人,总工作时间为 2。
③ 分 1 组,这一组 3 人,总工作时间为 3。
所以不同的总工作时间数为 3。

#include<cstdio>
int p[1000001],cnt;
bool us[1000001];
int n;
long long f[2][1001];
long long ans;
void get(){
    for(int i=2;i<=n;i++){
        if(!us[i]) p[++cnt]=i;
        for(int j=1;j<=cnt&&p[j]*i<=n;j++){
            us[p[j]*i]=1;
            if(!(i%p[j])) break;
        }
    }
}
int main(){
    freopen("textile.in","r",stdin);
    freopen("textile.out","w",stdout);
    scanf("%d",&n);
    get();
    int I=1;
    f[I^1][0]=1;
    for(int i=1;i<=cnt;i++){
        for(int j=0;j<=n;j++){
            f[I][j]=f[I^1][j];
            for(int k=p[i];k<=j;k*=p[i]){
                f[I][j]+=f[I^1][j-k];//w=p[i]^x
            }
        }
        I^=1;
    }
    for(int i=0;i<=n;i++){
        ans+=(long long)f[I^1][i];
    }
    printf("%lld\n",ans);
    return 0;
}

丝(filament)
【题目描述】
小 H 对于毛线球情有独钟,这一天他从中抽出了一根丝。
他发现,丝可以被等分成 n 段,且每一段都有一种颜色 ai,而令
他惊奇的是,从这一段丝似乎可以看出颜色是有循环节的,而且是纯
循环,由此他推断整个毛线球就是一段 纯循环的颜色序列。假设小 H
抽出的这一根丝恰好是整团毛线的 一端, 他希望找出 可能的最小的循
环节。
【输入数据】
第一行一个正整数 T,表示数据组数。
接下来每两行表示一组数据:第一行一个正整数 n,表示丝的长
度;第二行 n 个整数,表示每一段的颜色, 规定第 1 段为整团毛线的
一端。
【输出数据】
输出共 T 行,对于每组数据,输出一行表示最小循环节长度。
【样例输入】
2
3
1 2 1
2
1 1
【样例输出】
2
1
【数据范围】
对于 20%的数据,n<=500;
对于 40%的数据,n<=2000;
另外 20%的数据,满足最小循环节长度整除 n。
对于 100%的数据,1<=T<=5,1<=T*n<=10^6,0<=|ai|<=10^9。
【样例解释】
第一组数据,循环节为 1 2,整团毛线可能是 1 2 1 2……。
第二组数据,循环节为 1,整团毛线可能是 1 1 1 1……。

#include<cstdio>
#include<cstring>  
inline void read(int &x){  
    x=0;  
    int f=1;char c=getchar();  
    while(c<'0'||c>'9') {if(c=='-') f=-f; c=getchar();}  
    while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar();  
    x*=f;  
}  
int b[1000001],next[1000001];
int T,n,ans;
void getnext(){  
    int j=0,k=-1;  
    next[0]=-1;  
    while(j<n){  
        if(k==-1||b[j]==b[k]){  
            ++j;++k;  
            next[j]=k;  
        }  
        else{  
            k=next[k];  
        }  
    }  
}    
int main(){
    freopen("filament.in","r",stdin);
    freopen("filament.out","w",stdout);
    read(T);
    while(T--){
        memset(next,0,sizeof(next));
        read(n);
        for(int i=0;i<n;i++){
            read(b[i]);
        }
        getnext();
        printf("%d\n",n-next[n]);
        ans=0;
    }
    return 0;  
}  

 

posted on 2017-10-06 15:44  nzher  阅读(192)  评论(0编辑  收藏  举报