题目名称

正确答案

序列问题

长途旅行

英文名称

answer

sequence

travel

输入文件名

answer.in

sequence.in

travel.in

输出文件名

answer.out

sequence.out

travel.out

时间限制

1s

1s

1s

空间限制

256M

256M

256M

测试点数目

20

20

10

测试点分值

5

5

10

是否有部分分

题目类型

传统

传统

传统

是否有SPJ

1.正确答案

【题目描述】

小H与小Y刚刚参加完UOIP外卡组的初赛,就迫不及待的跑出考场对答案。

“吔,我的答案和你都不一样!”,小Y说道,”我们去找神犇们问答案吧”。

外卡组试卷中共有m道判断题,小H与小Y一共从其他n个神犇那问了答案。之后又从小G那里得知,这n个神犇中有p个考了满分,q个考了零分,其他神犇不为满分或零分。这可让小Y与小H犯了难。你能帮助他们还原出标准答案吗?如有多解则输出字典序最小的那个。无解输出-1。

【输入格式】

第一行四个整数n, m, p, q,意义如上描述。

接下来n行,每一行m个字符’N’或’Y’,表示这题这个神犇的答案。

【输出格式】

仅一行,一个长度为m的字符串或是-1。

【样例输入】

2 2 2 0

YY

YY

【样例输出】

YY

【数据范围】

30% : n <= 100.

60% : n <= 5000 , m <= 100.

100% : 1 <= n <= 30000 , 1 <= m <= 500.  0 <= p , q 且 p + q <= n.

暴力50:

  1. /*
  2. 自己还是太弱~没看出来要用hash 只是觉得自己的作法慢~
  3. QAQ
  4. 50分暴力 先排序 一样的缩成一种 然后枚举正确答案是哪个
  5. q==0 p==0的情况没考虑到~
  6. */
  7. #include<iostream>
  8. #include<cstdio>
  9. #include<cstring>
  10. #include<algorithm>
  11. #define maxn 30010
  12. #define maxm 510
  13. using namespace std;
  14. int n,m,p,q,cnt;
  15. string g[maxn];
  16. struct node{
  17. int len;
  18. string s;
  19. }k[maxn];
  20. int cmp(int a[maxm],int b[maxm]){
  21. for(int i=;i<=m;i++){
  22. if(a[i]<b[i])return ;
  23. if(a[i]>b[i])return ;
  24. }
  25. return ;
  26. }
  27. int main()
  28. {
  29. freopen("answer.in","r",stdin);
  30. freopen("answer.out","w",stdout);
  31. scanf("%d%d%d%d",&n,&m,&p,&q);
  32. for(int i=;i<=n;i++)cin>>g[i];
  33. sort(g+,g++n);
  34. int l=,r;
  35. for(r=;r<=n;r++){
  36. if(g[r]==g[l])continue;
  37. k[++cnt].s=g[l];
  38. k[cnt].len=r-l;l=r;
  39. }
  40. k[++cnt].s=g[l];
  41. k[cnt].len=r-l;
  42. int falg=;
  43. for(int i=;i<=cnt;i++){
  44. if(k[i].len!=p)continue;
  45. int sum=;
  46. string x;x.clear();
  47. for(int j=;j<m;j++)
  48. if(k[i].s[j]=='Y')x+='N';
  49. else x+='Y';
  50. for(int j=;j<=cnt;j++)
  51. if(k[j].s==x){
  52. sum+=k[j].len;
  53. break;
  54. }
  55. if(sum==q){
  56. cout<<k[i].s;
  57. falg=;break;
  58. }
  59. }
  60. if(falg==)
  61. for(int i=;i<=cnt;i++){
  62. if(k[i].len!=q)continue;
  63. int sum=;
  64. string x;x.clear();
  65. for(int j=;j<m;j++)
  66. if(k[i].s[j]=='Y')x+='N';
  67. else x+='Y';
  68. for(int j=;j<=cnt;j++)
  69. if(k[j].s==x){
  70. sum+=k[j].len;
  71. break;
  72. }
  73. if(sum==p){
  74. cout<<x;
  75. falg=;break;
  76. }
  77. }
  78. if(!falg)printf("-1\n");
  79. return ;
  80. }

正解hash:

  1. /*
  2. 正解hash
  3. 思路和之前的有相似之处
  4. 先排序 只不过没有类似离散化的处理
  5. 把每个人的答案放入hash表 这里用链表处理了碰撞的情况
  6. 然后同样的枚举正确答案 这不过用了hash表加速
  7. 对于pq==0的情况 枚举答案 按字典序小的来
  8. 那难道不会T到飞吗 不成了2^500的了吗
  9. 答案是不会的 这里的枚举是针对pq==0的情况来的
  10. 结束的条件是 找到与每个人都不一样的(存在一个即可)的就停下
  11. 所以枚举最多30000次
  12. */
  13. #include<iostream>
  14. #include<cstdio>
  15. #include<cstring>
  16. #include<algorithm>
  17. #define maxn 100010
  18. #define mod 10007
  19. #define MOD 23333
  20. #define bas 19
  21. #define BAS 119
  22. using namespace std;
  23. int n,m,p,q,hash[maxn],HASH[maxn],ans,falg;
  24. int num,head[maxn],cnt[maxn],t,T;
  25. struct edge{
  26. int v,pre;
  27. }e[maxn*];
  28. struct node{
  29. char s[];
  30. bool operator < (const node &x) const {
  31. return strcmp(s,x.s)<;
  32. }
  33. }a[maxn];
  34. void Insert(int from,int to){
  35. for(int i=head[from];i;i=e[i].pre)
  36. if(e[i].v==to){
  37. cnt[i]++;return;
  38. }
  39. num++;e[num].v=to;
  40. e[num].pre=head[from];
  41. head[from]=num;
  42. cnt[num]++;
  43. }
  44. int Query(int from,int to){
  45. for(int i=head[from];i;i=e[i].pre)
  46. if(e[i].v==to)return cnt[i];
  47. return ;
  48. }
  49. void Yan(){
  50. for(int i=;i<=n;i++){
  51. t=,T=;
  52. for(int j=;j<m;j++){
  53. t=t*bas+(a[i].s[j]=='Y');t%=mod;
  54. T=T*BAS+(a[i].s[j]=='Y');T%=MOD;
  55. }
  56. hash[i]=t;HASH[i]=T;
  57. Insert(t,T);
  58. }
  59. for(int i=;i<=n;i++){
  60. if(Query(hash[i],HASH[i])==p){
  61. int t=,T=;
  62. for(int j=;j<m;j++){
  63. t=t*bas+(a[i].s[j]=='N');t%=mod;
  64. T=T*BAS+(a[i].s[j]=='N');T%=MOD;
  65. }
  66. if(Query(t,T)==q){
  67. ans=i;
  68. falg=;break;
  69. }
  70. if(falg)break;
  71. }
  72. }
  73. if(falg)printf("%s\n",a[ans].s);
  74. else printf("-1\n");
  75. }
  76. void Li(){
  77. for(int i=;i<=n;i++){
  78. int t=,T=;
  79. for(int j=;j<m;j++){
  80. t=t*bas+(a[i].s[j]=='Y');t%=mod;
  81. T=T*BAS+(a[i].s[j]=='Y');T%=MOD;
  82. }
  83. hash[i]=t;HASH[i]=T;
  84. Insert(t,T);
  85. }
  86. for(int i=n;i>=;i--){
  87. if(Query(hash[i],HASH[i])==q){
  88. t=,T=;
  89. for(int j=;j<m;j++){
  90. t=t*bas+(a[i].s[j]=='N');t%=mod;
  91. T=T*BAS+(a[i].s[j]=='N');T%=MOD;
  92. }
  93. if(Query(t,T)==p){
  94. ans=i;
  95. falg=;break;
  96. }
  97. if(falg)break;
  98. }
  99. }
  100. if(falg){
  101. for(int i=;i<m;i++)
  102. if(a[ans].s[i]=='N')printf("Y");
  103. else printf("N");
  104. }
  105. else printf("-1\n");
  106. }
  107. void Feng(){
  108. for(int i=;i<=n;i++){
  109. t=,T=;
  110. for(int j=;j<m;j++){
  111. t=t*bas+(a[i].s[j]=='Y');t%=mod;
  112. T=T*BAS+(a[i].s[j]=='Y');T%=MOD;
  113. }
  114. Insert(t,T);
  115. t=;T=;
  116. for(int j=;j<m;j++){
  117. t=t*bas+(a[i].s[j]=='N');t%=mod;
  118. T=T*BAS+(a[i].s[j]=='N');T%=MOD;
  119. }
  120. Insert(t,T);
  121. }
  122. char r[];
  123. for(int i=;i<m;i++)r[i]='N';
  124. while(){
  125. t=,T=;
  126. for(int i=;i<m;i++){
  127. t=t*bas+(r[i]=='Y');t%=mod;
  128. T=T*BAS+(r[i]=='Y');T%=MOD;
  129. }
  130. if(Query(t,T)==){
  131. falg=;break;
  132. }
  133. for(int i=m-;i>=;i--)
  134. if(r[i]=='Y')r[i]='N';
  135. else{
  136. r[i]='Y';break;
  137. }
  138. }
  139. if(falg)printf("%s\n",r);
  140. else printf("-1\n");
  141. }
  142. int main()
  143. {
  144. freopen("answer.in","r",stdin);
  145. freopen("answer.out","w",stdout);
  146. scanf("%d%d%d%d",&n,&m,&p,&q);
  147. for(int i=;i<=n;i++)
  148. scanf("%s",a[i].s);
  149. sort(a+,a++n);
  150. if(p)Yan();
  151. else if(q)Li();
  152. else Feng();
  153. return ;
  154. }

2.序列问题

【题目描述】

小H是个善于思考的学生,她正在思考一个有关序列的问题。

她的面前浮现出了一个长度为n的序列{ai},她想找出两个非空的集合S、T。

这两个集合要满足以下的条件:

1. 两个集合中的元素都为整数,且都在 [1, n] 里,即Si,Ti ∈ [1, n]。

2. 对于集合S中任意一个元素x,集合T中任意一个元素y,满足x < y。

3. 对于大小分别为p, q的集合S与T,满足

a[s1] xor a[s2] xor a[s3] ... xor a[sp] = a[t1] and a[t2] and a[t3] ... and a[tq].

小H想知道一共有多少对这样的集合(S,T),你能帮助她吗?

【输入格式】

第一行,一个整数n

第二行,n个整数,代表ai。

【输出格式】

仅一行,表示最后的答案。

【样例输入】

4

1 2 3 3

【样例输出】

4

【样例解释】

S = {1,2}, T = {3}, 1 ^ 2 = 3 = 3 (^为异或)

S = {1,2}, T = {4},  1 ^ 2 = 3 = 3

S = {1,2}, T = {3,4}  1 ^ 2 = 3 & 3 = 3 (&为与运算)

S = {3}, T = {4}  3 = 3 = 3

【数据范围】

30%:
1 <= n <= 10

60%:
1 <= n <= 100

100%:
1 <= n <= 1000, 0 <= ai < 1024

  1. /*
  2. 30分暴力枚举集合不说了
  3. 其实这题需要高精的....
  4. 维护i到n &值为j的方案数
  5. 维护1到i ^值为j的方案数
  6. 然后枚举断点 乘起来
  7. */
  8. #include<iostream>
  9. #include<cstdio>
  10. #include<cstring>
  11. #define maxn 2050
  12. #define ll long long
  13. using namespace std;
  14. ll n,a[maxn],b[maxn],sum[maxn],f[maxn][maxn+],g[maxn][maxn+],ans;
  15. int main()
  16. {
  17. freopen("sequence.in","r",stdin);
  18. freopen("sequence.out","w",stdout);
  19. cin>>n;
  20. for(ll i=;i<=n;i++)
  21. cin>>a[i];
  22. for(ll i=;i<=n;i++)
  23. b[i]=a[n-i+];
  24. for(ll i=;i<=n;i++){
  25. for(ll j=;j<=;j++)
  26. f[i][j]=sum[j^a[i]];
  27. f[i][a[i]]++;
  28. for(ll j=;j<=;j++)
  29. sum[j]+=f[i][j];
  30. }
  31. memset(sum,,sizeof(sum));
  32. for(ll i=;i<n;i++){
  33. for(ll j=;j<=;j++)
  34. g[i+][j&b[i+]]+=sum[j];
  35. g[i+][b[i+]]++;
  36. for(ll j=;j<=;j++)
  37. sum[j]+=g[i+][j];
  38. }
  39. memset(sum,,sizeof(sum));
  40. for(ll i=;i<n;i++){
  41. for(ll j=;j<;j++)
  42. sum[j]+=f[i][j];
  43. for(ll j=;j<;j++)
  44. ans+=sum[j]*g[n-i][j];
  45. }
  46. cout<<ans;
  47. return ;
  48. }

3.长途旅行

【题目描述】

JY是一个爱旅游的探险家,也是一名强迫症患者。现在JY想要在C国进行一次长途旅行,C国拥有n个城市(编号为0,1,2...,n - 1),城市之间有m条道路,可能某个城市到自己有一条道路,也有可能两个城市之间有多条道路,通过每条道路都要花费一些时间。JY从0号城市开始出发,目的地为n – 1号城市。由于JY想要好好参观一下C国,所以JY想要旅行恰好T小时。为了让自己的旅行更有意思,JY决定不在任何一个时刻停留(走一条到城市自己的路并不算停留)。JY想知道是否能够花恰好T小时到达n – 1号城市(每个城市可经过多次)。现在这个问题交给了你。

若可以恰好到达输出“Possible”否则输出“Impossible”。(不含引号)。

【输入格式】

第一行一个正整数Case,表示数据组数。

每组数据第一行3个整数,分别为n, m, T。

接下来m行,每行3个整数x, y, z,代表城市x和城市y之间有一条耗时为z的双向边。

【输出格式】

对于每组数据输出”Possible”或者”Impossible”.

【样例输入】

2

3 3 11

0 2 7

0 1 6

1 2 5

2 1 10000

1 0 1

【样例输出】

Possible

Impossible

【样例解释】

第一组:0 -> 1 -> 2 :11

第二组:显然偶数时间都是不可能的。

【数据范围】

30%:  T <= 10000

另有30%: n <= 5 , m <= 10.

100%: 2 <= n <= 50 , 1 <= m <= 100 , 1 <= z <= 10000 , 1 <= T <= 10^18 , Case <= 5.

 暴力dp30:

  1. /*
  2. 暴力dp 30
  3. 状态f[i][j]表示到了i号节点走了j的状态是否存在
  4. 可以水过T比较小的数据
  5. */
  6. #include<iostream>
  7. #include<cstdio>
  8. #include<cstring>
  9. #define maxn 1000010
  10. using namespace std;
  11. int T,t,n,m,f[][maxn],g[][];
  12. void Clear(){
  13. memset(f,,sizeof(f));
  14. memset(g,,sizeof(g));
  15. }
  16. int main()
  17. {
  18. freopen("travel.in","r",stdin);
  19. freopen("travel.out","w",stdout);
  20. scanf("%d",&T);
  21. while(T--){
  22. scanf("%d%d%d",&n,&m,&t);
  23. int u,v,s;Clear();
  24. for(int i=;i<=m;i++){
  25. scanf("%d%d%d",&u,&v,&s);
  26. u++;v++;
  27. g[u][v]=g[v][u]=s;
  28. }
  29. f[][]=;
  30. for(int j=;j<=t;j++)
  31. for(int i=;i<=n;i++)
  32. for(int k=;k<=n;k++){
  33. if(!g[i][k]||j-g[i][k]<)continue;
  34. f[i][j]=f[i][j]||f[k][j-g[i][k]];
  35. }
  36. if(f[n][t])printf("Possible\n");
  37. else printf("Impossible\n");
  38. }
  39. return ;
  40. }

正解SFPA:

  1. /*
  2. 正解是最短路~~~~
  3. 一开始以为图论 后来认为是dp 没想到最后又回到图论了~~
  4. 前面dp做法的瓶颈很显然是T太大~
  5. 但是出入的边的权值和要小的多 所以会在某个环了转圈
  6. 假设有一条路径走一遍的时间为t 中间有一个长度为p的环
  7. 那这条路可以认为是t+p*k长度的
  8. 所以我们只需要维护这个多出来的t就好了 先选一个环
  9. 保险起见 选从零出发的最小的环 长度设为x
  10. 定义dis[i][j] 表示到了i 时间为j+k*x 且k最小 这里跑最短路找最小
  11. 为什么找最小呢 因为只有当dis[n][T%x]<=T 时才可以 所以为了尽量满足条件
  12. 维护最小的dis
  13. */
  14. #include<iostream>
  15. #include<cstdio>
  16. #include<cstring>
  17. #include<queue>
  18. #define maxn 210
  19. #define ll long long
  20. using namespace std;
  21. ll T,t,n,m,num,head[maxn],dis[maxn][maxn*],mxx,f[maxn][maxn];
  22. struct node{
  23. ll v,t,pre;
  24. }e[maxn*];
  25. struct point{
  26. int v,s;
  27. };
  28. queue<point>q;
  29. void Clear(){
  30. memset(head,,sizeof(head));
  31. memset(f,,sizeof(f));
  32. num=;
  33. }
  34. ll min(ll a,ll b){
  35. return a<b?a:b;
  36. }
  37. void Add(ll from,ll to,ll dis){
  38. num++;e[num].v=to;
  39. e[num].t=dis;
  40. e[num].pre=head[from];
  41. head[from]=num;
  42. }
  43. void SPFA(){
  44. memset(dis,/,sizeof(dis));
  45. q.push((point){,});
  46. f[][]=;dis[][]=;
  47. while(!q.empty()){
  48. ll x=q.front().v;
  49. ll s=q.front().s;
  50. q.pop();f[x][s]=;
  51. for(int i=head[x];i;i=e[i].pre){
  52. ll v=e[i].v;
  53. ll di=s+e[i].t;
  54. di%=mxx;//这里分清谁做下标谁是dis值
  55. if(dis[v][di]>s+e[i].t){
  56. dis[v][di]=s+e[i].t;
  57. if(f[v][di]==){
  58. f[v][di]=;
  59. q.push((point){v,di});
  60. }
  61. }
  62. }
  63. }
  64. }
  65. int main()
  66. {
  67. freopen("travel.in","r",stdin);
  68. freopen("travel.out","w",stdout);
  69. cin>>T;
  70. while(T--){
  71. cin>>n>>m>>t;
  72. ll u,v,s;Clear();
  73. mxx=0x7fffffff;
  74. for(int i=;i<=m;i++){
  75. cin>>u>>v>>s;
  76. u++;v++;
  77. Add(u,v,s);Add(v,u,s);
  78. if(u==||v==)mxx=min(mxx,s);
  79. }
  80. if(mxx==0x7fffffff){//不连通
  81. printf("Impossible\n");
  82. continue;
  83. }
  84. mxx*=;
  85. SPFA();
  86. if(dis[n][t%mxx]<=t)printf("Possible\n");
  87. else printf("Impossible\n");
  88. }
  89. return ;
  90. }

9.5noip模拟试题的更多相关文章

  1. 模拟试题C

    模拟试题C 一.单项选择题(2′*14 =28′) 1.双线性法向插值法(Phong Shading)的优点是( ) A)法向计算精确 B)高光域准确 C)对光源和视点没有限制 D)速度较快 2.用编 ...

  2. 模拟试题B

    模拟试题B 一.单项选择题(2′*8 =16′) 1.灰度等级为256级,分辨率为2048*1024的显示器,至少需要的帧缓存容量为( ) A)512KB B)1MB C)2MB D)3MB 2.在多 ...

  3. 模拟试题A

    模拟试题A 一.单项选择题(2′*12=24′) 1.下面各种坐标变换中,会产生变换前后维度的改变的是( ) A)建模变换 B)观察变换 C)投影变换 D)视口变换 2.下列描述深度缓冲消隐算法的特点 ...

  4. CCF 模拟试题——出现次数最多的数 官方答案解析及自己写的正确答案

    前几天知道的CCF计算机职业资格认证考试,觉得好像比软考含金量高一些,就去了解了一下,做了模拟试题中的 “出现次数最多的数” 这道题,我的算法和官方答案算法不同,个人觉得觉得官方的好一点,没那么繁琐, ...

  5. 11.9 noip模拟试题

    NOIP2016 模拟赛——那些年,我们学过的文化课背单词(word.c/cpp/pas)[题目描述]fqk 退役后开始补习文化课啦, 于是他打开了英语必修一开始背单词. 看着满篇的单词非常头疼, 而 ...

  6. 10.26 noip模拟试题

    enc[问题背景]zhx 和他的妹子聊天.[问题描述]考虑一种简单的加密算法.假定所有句子都由小写英文字母构成,对于每一个字母,我们将它唯一地映射到另一个字母.例如考虑映射规则:a->b, b- ...

  7. 9.29noip模拟试题

    环上的游戏(cycle) 有一个取数的游戏.初始时,给出一个环,环上的每条边上都有一个非负整数.这些整数中至少有一个0.然后,将一枚硬币放在环上的一个节点上.两个玩家就是以这个放硬币的节点为起点开始这 ...

  8. 9.20 noip模拟试题

      Problem 1 双色球(ball.cpp/c/pas) [题目描述] 机房来了新一届的学弟学妹,邪恶的chenzeyu97发现一位学弟与他同名,于是他当起了善良的学长233 “来来来,学弟,我 ...

  9. 9.16noip模拟试题

    题目描述 在幻想乡,东风谷早苗是以高达控闻名的高中生宅巫女.某一天,早苗终于入手了最新款的钢达姆模型.作为最新的钢达姆,当然有了与以往不同的功能了,那就是它能够自动行走,厉害吧(好吧,我自重).早苗的 ...

随机推荐

  1. bzoj2395: [Balkan 2011]Timeismoney

    Description      有n个城市(编号从0..n-1),m条公路(双向的),从中选择n-1条边,使得任意的两个城市能够连通,一条边需要的c的费用和t的时间,定义一个方案的权值v=n-1条边 ...

  2. Linux——搭建PHP开发环境第四步:composer

    原文链接:https://my.oschina.net/jiangbianwanghai/blog/473249 1.下载composer.phar [root#localhost opt]# cur ...

  3. Thinking In Java 学习笔记 1-5 章

    第1章 对象导论 本章主要讲OOP的思想及一些OOP基本概念 1.抽象过程:万物都是对象,对象具有状态.行为和标识.对象拥有属性和方法,以及在内存中的唯一地址. 2.每个对象都有一个接口:通过接口给对 ...

  4. Extjs打开window窗口自动加载html网页

    Window inherits the autoLoad config option from Panel. Note that I included all config options below ...

  5. Billboard

    hdu2795:http://acm.hdu.edu.cn/showproblem.php?pid=2795 题意:给一个h*w的公告牌,h是高度,w是宽度,一个单位高度1为一行,然后会有一些公告贴上 ...

  6. Maven实战一

    转载:http://www.iteye.com/topic/1123221 1. 用Maven 命令创建一个简单的Maven项目 在cmd中运行如下命令: Cmd代码 mvn archetype:ge ...

  7. c++ explicit

    C++ explicit关键字用来修饰类的构造函数,表明该构造函数是显式的,既然有"显式"那么必然就有"隐式",那么什么是显示而什么又是隐式的呢? 如果c++类 ...

  8. 两款商业拓扑发现软件siteview和ElementSentry的比较

    今天在公司试用了一下两款商业拓扑发现软件游龙科技的siteview和速方软件ElementSentry. 条目/产品 速方软件ElementSentryv5.0 游龙科技Siteview NNM v3 ...

  9. [OSX] 取消开机启动

    以Pulse Secure为例 参考:https://kb.pulsesecure.net/articles/Pulse_Secure_Article/KB26679 输入指令: launchctl ...

  10. POJ3617 Best Cow Line

    其实是学习参考了算法书的代码,但仍然是我自己写的,有小差别.贪心类型. #include <iostream> using namespace std; int main() { int ...