沈阳集训day3

来源:互联网 发布:企业如何在淘宝开店 编辑:程序博客网 时间:2024/05/01 13:07

非常地伤心,最水的一道题freopen没加,少了100分,本来是rank3的,直接掉到rank15,当时都以为自己考出来了,唉,这下肯定再也考不出来了,差距越拉越大了,真的非常伤心,这几天运气还真是好


信息学奥赛校际联训
模拟测试3
东北育才中学命制
竞赛时间:2017年6月3日7:30-12:30
题目名称 集合 计算器 上网 计数
英文名称 set calculator net count
目录 set calculator net count
可执行文件名 set calculator net count
输入文件名 set.in calculator.in net.in count .in
输出文件名 set.out calculator.out net.out count .out
每个测试点时限 1 秒 3 秒 1 秒 1 秒
内存限制 256 MB 256 MB 256 MB 256 MB
试题总分 100 100 100 100
测试点数目 10 10 10 10
每个测试点分值 10 10 10 10
是否有部分分 否 否 否 否
题目类型 传统型 传统型 传统型 传统型

提交源程序须加后缀
对于C++ 语言 set.cpp calculator.cpp net.cpp count.cpp
对于C 语言 set.c calculator.c net.c count.c
对于Pascal语言 set.pas calculator.pas net.pas count.pas

注意:最终测试时,所有编译命令均不打开任何优化开关。
集合(set)
【问题描述】
集合是数学中的一个概念,用通俗的话来讲就是:一大堆数在一起就构成了集合。集合有如下的特性:
·无序性:任一个集合中,每个元素的地位都是相同的,元素之间是无序的。
互异性:一个集合中,任何两个元素都认为是不相同的,即每个元素只能出现一次。
定性:给定一个集合,任给一个元素,该元素或者属于或者不属于该集合,二者必居其一,不允许有模棱两可的情况出现。
例如 A = {1, 2, 3} 就是一个集合。我们可以知道, 1 属于 A ,即 1 ∈ A ; 4 不属于 A ,即 4 ∉ A 。一个集合的大小,就是其中元素的个数。
现在定义一个特殊的 k-集合,要求满足:
集合的所有特性
对任意一个该集合内的元素 x ,不存在一个数 y ,使得 y = kx 并且 y 属于该集合。即集合中的任意一个数,它乘以 k 之后的数都不在这个集合内
给你一个由 n 个不同的数组成的集合,请你从这个集合中找出一个最大的 k-集合。
【输入格式】
从文件set.in中输入数据。
第一行:两个整数n、k
第 2 行:n 个整数: a[i] 表示给定的集合
【输出格式】
输出到文件set.out中。
第 1 行:一个整数: ans 表示最大的 k-集合的大小
【样例输入】
6 2
2 3 6 5 4 10
【样例输出】
3
【样例解释】
在样例所给集合中,找出的最大的 2-集合为 {4, 5, 6}
【数据规模与约定】
对于 40% 的数据: a[i] ≤ 231-1
对于 70% 的数据: n, k ≤ 5000
对于 100% 的数据: n, k ≤ 105, a[i] ≤ 263-1
计算器(calculator)
【问题描述】
Tom得到了一个计算器,这个计算器有两个整数单元,一开始,第一个单元包含数字1,第二个单元包含数字0。 这个计算器支持一以下两种操作:
假设第一个单元的数字为a,第二个单元的数字为b,那么将第二个单元的数字改成b+1。
假设第一个单元的数字为a,第二个单元的数字为b,那么将第一个单元的数字改成a*b。
现在Tom想知道,有多少个正整数x(l<=x<=r)满足, 存在一种方式从计算器初始状态开始,操作不超过p步之后使得第一个单元中的数字为x。
【输入格式】
从文件calculator.in中输入数据。
共一行,为三个空格隔开的正整数l,r,p(2<=l<=r<=10^9, 1<=p<=100)
【输出格式】
输出到文件calculator.out中。
输出仅一行一个整数ans,即为问题所求。
【样例输入1】
2 10 3
【样例输出1】
1
【样例输入2】
2 111 100
【样例输出2】
106
【样例输入3】
2 111 11
【样例输出3】
47
【数据规模与约定】
对于30%的数据,2<=l<=r<=10^6,1<=p<=15。
另外20%的数据满足,2<=l=r<=10^9,1<=p<=100。
对于100%的数据,2<=l<=r<=10^9,1<=p<=100。
上网(net)
【问题描述】
有 n 个人要上网,却只有 1 台电脑可以上网。上网的时间是从 1 AM 至 T AM,AM 是自创的时间单位,至于 AM 怎么换算成 s,min 或 h,没有人清楚。依次给出每个人在某个时间段内上网的快乐程度 C(必须这个人在整个时间段内都在上网,才能获得快乐程度 C,否则,快乐程度是 0),请你求出可以达到的最大总快乐程度。
【输入格式】
从文件net.in中输入数据。
第 1 行 2 个整数 n 和 T,含义如题目所述;
接下来有 n 个这样的结构(每两个相邻的结构之间有一空行,且第 1 个结构和第一行间有一空行):
第 1 行一个整数 Mi,表示第 i 个人的时间段的个数;接下来有 Mi行,每行 3 个整数 Xj,Yj,Cj,表示第 i 个人在[Xj,Yj]内上网的快乐程度为 Cj,因此有 Xj-Yj-1=1,X1=1,Ymi=T,Xj≤Yj。
【输出格式】
输出到文件net.out中。
仅输出一行,为最大的总快乐程度。
【样例输入1】

3 10

3
1 3 6
4 7 9
8 10 3

3
1 3 5
4 7 10
8 10 1

4
1 3 2
4 8 2
9 9 6
10 10 3
【样例输出1】
25
【样例解释】
在[1,3]内,安排 1 上网,快乐程度为 6;
在[4,7]内,安排 2 上网,快乐程度为 10;
在[8,8]内,不安排;
在[9,9]内,安排 3 上网,快乐程度为 6;
在[10,10]内,安排 3 上网,快乐程度为 3;
这是使总的快乐程度达到最大的方案,对应的值是 25。
【数据规模与约定】
对于 30%的数据,n≤4,所有的 Mi≤5,T≤20;
对于 60%的数据,n≤100,所有的 Mi≤100,T≤2000;
对于 100%的数据,n≤500,所有的 Mi≤500,T≤500000,所有的 0< C≤109,并保证最终解 Max≤109。
计数(count)
【问题描述】
OIER的生活总是满足“一些好事,然后一些坏事,然后一些好事”这样的规律。所以OIER认为接下来的n天也是满足这样的规律的。
OIER知道,接下来会发生w件两两不同的好事和b件两两不同坏事,每天至少发生一件事,每天要么全部发生好事要么全部发生坏事。
由于OIER的规律,这n天会先有若干天发生好事,再有若干天发生坏事,再有若干天发生好事(若干代指>0)。
要求统计事件发生的方案数(每天发生的事的顺序也不一样),答案取模10^9+9输出。
【输入格式】
从文件count.in中输入数据。
三个正整数n,w,b
【输出格式】
输出到文件count.out中。
一个正整数,表示方案数。
【样例输入】
4 2 2
【样例输出】
4
【数据规模与约定】
对于 30%的数据,n,w,b<=10
对于 100%的数据,3<=n<=4000,2<=w<=4000,1<=b<=4000,w+b>=n
t1代码

#include<cstdio>#include<iostream>#include<cstring>#include<set>#include<algorithm>#define dnt long long #define MAXN 100000+10using namespace std;dnt set_pri[MAXN];set<dnt>s;int n,k;int main(){    freopen("set.in","r",stdin);    freopen("set.out","w",stdout);     scanf("%d%d",&n,&k);    for(register int i=1;i<=n;i++)scanf("%lld",&set_pri[i]);    sort(set_pri+1,set_pri+n+1);    for(int i=1;i<=n;i++){        if(set_pri[i]%k||s.find(set_pri[i]/k)==s.end()){            s.insert(set_pri[i]);        }    }    int size=s.size();    printf("%d",size);    return 0;}//这样思考贪心策略:首先,如果一个数不能被k整除,那么他不会对比他小的数造成影响,如果选择他或者不选择他对后面的kx造成了影响,那么也只是选或者不选kx//对于kx*x是不会造成影响的,因为如果选择kx会对k*x*x造成影响,因此这样的贪心策略是可以的,另外一个判定是是否已经存在/k的数, 

t3代码

#include<cstdio>#include<iostream>#include<cstring>#include<algorithm>#define MAXN 300000+10#define MAXNN 500000+10using namespace std;struct Line{    int x,y,c;}line[MAXN];int C[MAXNN];/*struct seg{    int left,right,maxn;}seg[MAXNN];*/int tail,n,T,t,xx,yy,cc;bool cmp(Line l,Line r){ return l.y<r.y; }int lowbit(int x){ return x&(-x); }void add_line(int x,int y,int c){    tail++;    line[tail].x=x;    line[tail].y=y;    line[tail].c=c;}int query(int x){    int maxn=0;    while(x){        int y=lowbit(x);        maxn=max(maxn,C[x]);        x-=y;    }    return maxn;}void modify(int x,int y){    while(x<=T){        C[x]=max(C[x],y);        x+=lowbit(x);    }}/*void pushup(int rt){    seg[rt].maxn=max(seg[rt<<1].maxn,seg[rt<<1|1].maxn);}*//*void build(int rt,int left,int right){    if(left==right){        seg[rt].maxn=0;        return;    }    int mid=(l+r)>>1;    build(rt<<1,left,mid);    build(rt<<1|1,mid+1,right);    pushup(rt);}*/int main(){    freopen("net.in","r",stdin);    freopen("net.out","w",stdout);    scanf("%d%d",&n,&T);    for(int i=1;i<=n;i++){        scanf("%d",&t);        while(t--){            scanf("%d%d%d",&xx,&yy,&cc);            add_line(xx,yy,cc);        }    }     sort(line+1,line+tail+1,cmp);//  for(int i=1;i<=tail;i++){//      printf("%d ",line[i].y);//  }    //build(1,1,n);    for(int i=1;i<=tail;i++){        int tmp=query(line[i].x-1);        int happymax=query(line[i].x-1)+line[i].c;        int idy=query(line[i].y);        if(idy<happymax){            modify(line[i].y,happymax);        }    }    int final_ASS=query(T);    printf("%d",final_ASS);    return 0;}

t4代码

#include<cstdio>#include<iostream>#include<cstring>#define dnt long long#define MAXN 4000+10const int idy=1e9+9;using namespace std;int MAX(int x,int y){return x>y?x:y;}dnt f[MAXN];dnt c[MAXN][MAXN];int n,w,b;dnt final_ASS;dnt C(int n,int m){    if(c[n][m]>0) return c[n][m];    else if(m==0){ c[n][m]=1;return c[n][m];}    else {        if(n>=m+1){            return c[n][m]=(C(n-1,m)+C(n-1,m-1))%idy;        }else{            return c[n][m]=0+C(n-1,m-1);        }    }}int main(){    freopen("count.in","r",stdin);    freopen("count.out","w",stdout);    scanf("%d%d%d",&n,&w,&b);    int maxn=MAX(w,b);//好事多还是坏事多    f[0]=1;    for(dnt i=1;i<=maxn;i++)     f[i]=f[i-1]*i%idy;//%idy    for(int i=MAX(n-w,1);i<=n-2&&i<=b;i++){        final_ASS=(final_ASS+C(b-1,i-1)*f[b]%idy*f[w]*C(w-1,n-i-1)%idy*(n-i-1))%idy;    }    cout<<final_ASS<<endl;    return 0;} 

心情久久不能平静,我的100分啊

原创粉丝点击