9.28NOIP模拟题
9.28NOIP模拟题
题目 |
哈 |
哈哈 |
哈哈哈 |
英文题目与子目录名 |
ha |
haha |
hahaha |
单个测试点时间限制 |
1秒 |
1秒 |
1秒 |
内存限制 |
256M |
128M |
64M |
测试点数目 |
10 |
10 |
10 |
每个测试点分值 |
10 |
10 |
10 |
比较方式 |
全文比较(过滤行末空格及文末回车) |
||
题目类型 |
传统 |
传统 |
传统 |
哈
Description
求字符串的所有前缀在字符串中出现的次数和
Input
第一行一个整数L,表示字符串长度
一个字符串
Output
一行表示答案,答案对1000007取模
Example
Input:
4
abab
Output:
4
Hint
对于20%的数据,L<=50
对于50%的数据,L<=4000
对于70%的数据,L<=100000
对于100%的数据,L<=10000000
/* 假设两串字符完全相等,next[j]=i,代表s[1...i]==sum[j-i+1....j],这一段其实就是前缀 i~j之间已经不可能有以j结尾的子串是前缀了,不然next【j】就不是 i 了 设dp【i】:以string[i]结尾的子串总共含前缀的数量 所以dp[j]=dp[i]+1,即以i结尾的子串中含前缀的数量加上前j个字符这一前缀 */ #include <cstdio> #include <algorithm> #include <cstring> #include <cmath> #include <iostream> using namespace std; const int N = 200005; char a[N]; int next[N],d[N]; void get_next(char *b) { int i = -1, j = 0; next[0] = -1; int len = strlen(b); while(j < len) { if(i == -1 || b[i] == b[j]) next[++j] = ++i; else i = next[i]; } } int main() { int T,i,n; scanf("%d",&T); while(T--) { scanf("%d%s",&n,a); get_next(a); for(i = 1; i <= n; i ++) d[i] = 1; d[0] = 0; int sum = 0; for(i = 1; i <= n; i ++) { d[i] = d[next[i]] + 1; sum += d[i]%10007; } printf("%d\n",sum%10007); } return 0; }
哈哈
Description
有n个人准备去逛超市,其中第i个人买东西的概率是Pi 。逛完以后你得知有r个人买了东西,但不知道是哪r个人。请计算每个人实际买了东西的概率。输入n(1≤n≤20)和r(0≤r≤n),
输出每个人实际买了东西的概率。
Input
第一行两个整数n,r
接下来n行,每行一个实数,表示第i个人买东西的概率
Output
N行表示答案,保留3为小数,你的答案必须与标准输出完全一样才能得分
Example
Input
3 2
0.10
0.20
0.30
5 1
0.10
0.10
0.10
0.10
0.10
Output
0.413
0.739
0.848
0.200
0.200
0.200
0.200
0.200
Hint
对于20%的数据,n=2
对于另外30%的数据,n<=20,r=1
对于另外20%的数据,n<=10
对于100%的数据,n<=20,r<=n
你的答案必须与标准输出完全一致才能得分
/* 条件概率额计算 一道条件概率的题:条件概率公式:P(A|B)=P(AUB)/P(B) 简单来说,A在B发生的前提下发生的概率为2个都发生的概率除以B发生的概率。 所以这道题就是每个点发生的概率除以tot(m个人买的概率,不论是哪m个人)的值了。 枚举每个人买不买,把每种情况的概率记录下来,如果刚好m个人买了,那就让tot加这个值,然后这种情况每个买了的人的概率加这个值。 */ #include<cstdlib> #include<cstdio> #include<cstring> #include<iostream> using namespace std; int n,m; double bri[200],ans[200],tot; int vis[200]; void dfs(int i,int use_,double p) { if(i>n) { if(use_==m) { tot+=p; for(int i=1;i<=n;i++) if(vis[i]) ans[i]+=p; } return; } vis[i]=1;dfs(i+1,use_+1,p*bri[i]); vis[i]=0;dfs(i+1,use_,p*(1-bri[i])); } int main() { freopen("haha.in","r",stdin); freopen("haha.out","w",stdout); scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) scanf("%lf",&bri[i]); dfs(1,0,1); for(int i=1;i<=n;i++) printf("%.3lf\n",ans[i]/tot); fclose(stdin);fclose(stdout); return 0; }
哈哈哈
Description
有两个长度为 N 的序列 A 和 B,在 A 和 B 中各任取一个数可以得到 N^2 个和,求这N^2 个和中最小的 N个。
Input
一行一个整数n
第二行n个整数ai
第三行n个整数bi
Output
N行表示答案
Example
input
5
1 3 2 4 5
6 3 4 1 7
Output
2 3 4 4 5
Hint
20%的数据,n<=1000
50%的数据,n<=50000
70%的数据,n<=100000
100%的数据,n<=600000
保证答案<max_int
/* 优先队列维护最大的n个和 第一个数组从个头到位扫,动态维护 具体看代码 */ #include<iostream> #include<cstdio> #include<algorithm> #include<queue> #define N 200007 using namespace std; int a[N],b[N],ans[N]; int n,m,cnt,sum; priority_queue<int>que; inline int read() { int x=0,f=1;char ans=getchar(); while(ans>'9'||ans<'0'){if(ans=='-')f=-1;ans=getchar();} while(ans>='0'&&ans<='9'){x=x*10+ans-'0';ans=getchar();} return x*f; } int main() { freopen("hahaha.in","r",stdin); freopen("hahaha.out","w",stdout); n=read(); for(int i=1;i<=n;i++) a[i]=read(); for(int i=1;i<=n;i++) b[i]=read(); sort(a+1,a+n+1);sort(b+1,b+n+1); for(int i=1;i<=n;i++) { int now_=a[1]+b[i]; que.push(now_); } for(int i=2;i<=n;i++) for(int j=1;j<=n;j++) { sum=a[i]+b[j]; if(sum>=que.top()) break; else { que.pop(); que.push(sum); } } for(int i=1;i<=n;i++) { ans[i]=que.top(); que.pop(); } for(int i=n;i>=1;i--) printf("%d\n",ans[i]); fclose(stdin);fclose(stdout); return 0; }
折花枝,恨花枝,准拟花开人共卮,开时人去时。
怕相思,已相思,轮到相思没处辞,眉间露一丝。