西安赛区网络赛

1001、Post Robot

字符串匹配题题,子串长度不超过6,所以直接暴力。

(读一一行带空格的字符串,可以使用while(gets());)

 1 //============================================================================
 2 // Name        : 20140920.cpp
 3 // Author      : 
 4 // Version     :
 5 // Copyright   : Your copyright notice
 6 // Description : Hello World in C++, Ansi-style
 7 //============================================================================
 8 
 9 #include <iostream>
10 #include <iostream>
11 #include <stdio.h>
12 #include <math.h>
13 #include <string.h>
14 #include <vector>
15 #include <algorithm>
16 using namespace std;
17 #define LL __int64
18 char f[10010];
19 int main() {
20     freopen("in.txt", "r", stdin);
21     //freopen("out.txt","w",stdout);
22     while(gets(f)){
23         int len =strlen(f);
24         for(int i=0;i<len;i++){
25             if(f[i]=='A' && f[i+1]=='p' && f[i+2]=='p' && f[i+3]=='l' && f[i+4]=='e'){
26                 puts("MAI MAI MAI!");
27             }
28             else if(f[i]=='i' && f[i+1]=='P' && f[i+2]=='a' && f[i+3]=='d'){
29                 puts("MAI MAI MAI!");
30             }
31             else if(f[i]=='i' && f[i+1]=='P' && f[i+2]=='h' && f[i+3]=='o' && f[i+4]=='n' && f[i+5]=='e'){
32                 puts("MAI MAI MAI!");
33             }
34             else if(f[i]=='i' && f[i+1]=='P' && f[i+2]=='o' && f[i+3]=='d' ){
35                 puts("MAI MAI MAI!");
36             }
37             else if(f[i]=='S' && f[i+1]=='o' && f[i+2]=='n' && f[i+3]=='y' )
38                 puts("SONY DAFA IS GOOD!");
39         }
40     }
41 
42     return 0;
43 }
View Code

 

1002、Boring String Problem

后缀数组+RMQ+二分

后缀数组二分确定第K不同子串的位置 , 二分LCP确定可选的区间范围 , RMQ求范围内最小的sa

清华AC代码:(的确高大上,先贴着,参考学习)

 1 #include <algorithm>
 2 #include <cstring>
 3 #include <cstdlib>
 4 #include <cstdio>
 5 #define N 200010
 6 #define int64 long long
 7 #define For(i,x,y) for (i=x;i<=y;i++)
 8 using namespace std;
 9 struct ww {
10     int a,b;
11 } f[N][20];
12 int i,j,k,n,m,an,re;
13 int r[N],rr[N],sa[N],t[N],tt[N],h[N],len[N];
14 char p[N];
15 int64 preh[N];
16 inline void Sa() {
17     int i,j,k=30;
18     For(i,1,n) r[i]=p[i]-'a'+1;
19     For(i,n+1,N-1) r[i]=0;
20     for (i=1;i<=n;i<<=1) {
21         For(j,1,k) t[j]=0;
22         For(j,1,n) t[r[j+i]]++;
23         For(j,1,k) t[j]+=t[j-1];
24         for (j=n;j;j--) tt[t[r[j+i]]--]=j;
25         For(j,1,k) t[j]=0;
26         For(j,1,n) t[r[j]]++;
27         For(j,1,k) t[j]+=t[j-1];
28         for (j=n;j;j--) sa[t[r[tt[j]]]--]=tt[j];
29         rr[sa[1]]=k=1;
30         For(j,2,n) if (r[sa[j]]==r[sa[j-1]]&&r[sa[j]+i]==r[sa[j-1]+i])
31             rr[sa[j]]=rr[sa[j-1]]; else rr[sa[j]]=++k;
32         For(j,1,n) r[j]=rr[j];
33         if (k==n) return;
34     }
35 }
36 inline void Getheight() {
37     int i,j,k=0;
38     for (i=1;i<=n;h[r[i++]]=k) 
39     for (k?k--:0,j=sa[r[i]-1];p[j+k]==p[i+k];k++);
40 }
41 inline void pre() {
42     int i,j;
43     For(i,1,n) f[i][0]=(ww){h[i],sa[i]};
44     For(j,1,19)For(i,1,n-(1<<j)+1) {
45         int A=i+(1<<j-1);
46         f[i][j].a=min(f[i][j-1].a,f[A][j-1].a);
47         f[i][j].b=min(f[i][j-1].b,f[A][j-1].b);
48     }
49 }
50 inline int get(int x,int y) {
51     int i,an=N;
52     for (i=19;i>=0;i--) if (f[x][i].a>=y) an=min(an,f[x][i].b),x+=1<<i;
53     return an;
54 }
55 int main() {
56     //freopen("1002.in","r",stdin);
57     //freopen("1002.out","w",stdout);
58     for (;scanf("%s",p+1)!=EOF;) {
59         n=strlen(p+1);
60         Sa(); Getheight();
61         For(i,1,n) len[i]=n-sa[i]+1;
62         For(i,1,n) preh[i]=preh[i-1]+len[i]-min(len[i],h[i]);
63         an=re=0;
64         scanf("%d",&m);
65         pre();
66         For(i,1,m) {
67             int64 x;
68             scanf("%I64d",&x);
69             x=(x^an^re)+1;
70             if (x>preh[n]) an=re=0;
71             else {
72                 int l=1,r=n,mid;
73                 for (;l<=r;) {
74                     mid=(l+r)/2;
75                     if (preh[mid]<x) l=mid+1;
76                     else r=mid-1;
77                 }
78                 x-=preh[l-1];
79                 an=min(sa[l],get(l+1,h[l]+x));
80                 re=an+h[l]+x-1;
81             }
82             printf("%d %d\n",an,re);
83         }
84     }
85     return 0;
86 }
View Code

 

1003、

 DP

 

1005、

博弈,不会。

 

1006、Dice

·简单的bfs、这题重点在于每次正方体旋转之后的状态描述,状态保存;找到四种翻转之后的状态描述方式之后即可。

 ·bfs重点:

  记忆话搜索! int vis[] ;   //这里使用hash()函数的时候,可以使用一维变量,否则状态如何表示,记忆话的方式也如何表示。

  (这点很重要,不然很有可能会超时!)

  hash值代表状态,构造哈希函数。 int hash(int a[]){   return .. ;}

  队列的使用 #include <queue>

  每种状态的区分描述:  if ...  else if ... else if... 等 。   每一次进队的状态数量

  广搜题目,有时可以限制深度。(这道题:一共6!中情况)

经典bfs代码:(600+ms,方法比较慢)

  1 #include <iostream>
  2 #include <stdio.h>
  3 #include <stdlib.h>
  4 #include <string.h>
  5 #include <queue>
  6 using namespace std;
  7 
  8 int start[10],end[10];
  9 int vis[10][10][10][10][10][10];
 10 struct LNode{
 11     int f[7],ans; //描述状态以及当前深度。
 12 }t,m,f;
 13 
 14 int deal(){
 15     for(int i=1;i<=6;i++)
 16         if(t.f[i]==end[i]) continue;
 17         else return 0;
 18     return 1;
 19 }
 20 int bfs(){
 21     queue<LNode> q;
 22     for(int i=1;i<=6;i++) t.f[i] = start[i];  t.ans = 0;
 23     q.push(t);
 24     vis[t.f[1]][t.f[2]][t.f[3]][t.f[4]][t.f[5]][t.f[6]]=1; //进行标记
 25     while(!q.empty()){
 26         t = q.front();
 27         q.pop();
 28 
 29         //判断是否满足条件
 30         if(deal()) return t.ans;
 31         for(int i=1;i<=4;i++){
 32             if(i==1)
 33             {
 34                 f.f[1]=t.f[4];
 35                 f.f[2]=t.f[3];
 36                 f.f[3]=t.f[1];
 37                 f.f[4]=t.f[2];
 38                 f.f[5]=t.f[5];
 39                 f.f[6]=t.f[6];
 40                 if(vis[f.f[1]][f.f[2]][f.f[3]][f.f[4]][f.f[5]][f.f[6]]==0)
 41                 {
 42                     f.ans=t.ans+1;
 43                     vis[f.f[1]][f.f[2]][f.f[3]][f.f[4]][f.f[5]][f.f[6]]=1;  //进行标记!
 44                     q.push(f);
 45                 }
 46             }
 47             else if(i==2)
 48             {
 49                 f.f[1]=t.f[3];
 50                 f.f[2]=t.f[4];
 51                 f.f[3]=t.f[2];
 52                 f.f[4]=t.f[1];
 53                 f.f[5]=t.f[5];
 54                 f.f[6]=t.f[6];
 55                 if(vis[f.f[1]][f.f[2]][f.f[3]][f.f[4]][f.f[5]][f.f[6]]==0)
 56                 {
 57                     f.ans=t.ans+1;
 58                     vis[f.f[1]][f.f[2]][f.f[3]][f.f[4]][f.f[5]][f.f[6]]=1;
 59                     q.push(f);
 60                 }
 61             }
 62             else if(i==3)
 63             {
 64                 f.f[1]=t.f[6];
 65                 f.f[2]=t.f[5];
 66                 f.f[3]=t.f[3];
 67                 f.f[4]=t.f[4];
 68                 f.f[5]=t.f[1];
 69                 f.f[6]=t.f[2];
 70                 if(vis[f.f[1]][f.f[2]][f.f[3]][f.f[4]][f.f[5]][f.f[6]]==0)
 71                 {
 72                     f.ans=t.ans+1;
 73                     vis[f.f[1]][f.f[2]][f.f[3]][f.f[4]][f.f[5]][f.f[6]]=1;
 74                     q.push(f);
 75                 }
 76             }
 77             else if(i==4)
 78             {
 79                 f.f[1]=t.f[5];
 80                 f.f[2]=t.f[6];
 81                 f.f[3]=t.f[3];
 82                 f.f[4]=t.f[4];
 83                 f.f[5]=t.f[2];
 84                 f.f[6]=t.f[1];
 85                 if(vis[f.f[1]][f.f[2]][f.f[3]][f.f[4]][f.f[5]][f.f[6]]==0)
 86                 {
 87                     f.ans=t.ans+1;
 88                     vis[f.f[1]][f.f[2]][f.f[3]][f.f[4]][f.f[5]][f.f[6]]=1;
 89                     q.push(f);
 90                 }
 91             }
 92         }
 93     }
 94     return -1;
 95 }
 96 int main(){
 97     //freopen("in.txt","r",stdin);
 98     while(scanf("%d%d%d%d%d%d",&start[1],&start[2],&start[3],&start[4],&start[5],&start[6])!=EOF){
 99         for(int i=1;i<7;i++) scanf("%d",&end[i]);
100         memset(vis,0,sizeof(vis));
101         printf("%d\n",bfs());
102     }
103     return 0;
104 }
View Code

hash函数表示状态代码:(摘自网络)

  1 #include <cstdlib>
  2 #include <climits>
  3 #include <cassert>
  4 #include <cstdio>
  5 #include <cmath>
  6 #include <ctime>
  7 #include <functional>
  8 #include <algorithm>
  9 #include <memory.h>
 10 #include <numeric>
 11 #include <utility>
 12 #include <iomanip>
 13 #include <iostream>
 14 #include <sstream>
 15 #include <fstream>
 16 #include <cstring>
 17 #include <vector>
 18 #include <bitset>
 19 #include <deque>
 20 #include <queue>
 21 #include <stack>
 22 #include <list>
 23 #include <set>
 24 #include <map>
 25 
 26 #define MX 1000000
 27 using namespace std;
 28 
 29 int rot[4][10] = {{2, 1, 3, 0, 2}, {3, 1, 2, 0, 3}, {4, 1, 5, 0, 4}, {5, 1, 4, 0, 5}};
 30 
 31 int que[MX];
 32 int chk[MX], T;
 33 
 34 int hash(int a[]) {
 35     
 36     int i, v = 1, s = 0;
 37     for (i = 0; i < 6; i ++) {
 38         s += a[i] * v;
 39         v *= 7;    
 40     }    
 41     return s;
 42 }
 43 
 44 void get(int a[], int u) {
 45     
 46     int i;
 47     for (i = 0; i <= 5; i ++) {
 48         a[i] = u % 7;
 49         u /= 7;    
 50     }
 51 }
 52 
 53 int main() {
 54     
 55 //    freopen("in.txt", "r", stdin);
 56 //    freopen("out.txt", "w", stdout);
 57     
 58     int i, k, S, E, u, dp;
 59     int a[10], b[10], c[10], d[10], e[10];
 60     while (scanf("%d", &a[0]) == 1) {
 61         
 62         for (i = 1; i < 6; i ++) scanf("%d", a + i);
 63         for (i = 0; i < 6; i ++) scanf("%d", b + i);
 64         
 65         
 66         T ++;
 67         S = hash(a);
 68         E = hash(b);
 69         chk[S] = T;
 70 
 71         int bf = 0;
 72         int st = 0, en = 0;
 73         que[en ++] = S; que[en ++] = 0;
 74         while (st < en) {
 75             
 76             u = que[st ++]; dp = que[st ++];
 77 
 78             if (u == E) {
 79                 printf("%d\n", dp);
 80                 bf = 1;
 81                 break;    
 82             }
 83             get(c, u);
 84             for (i = 0; i < 4; i ++) {
 85                 if (i < 2) {
 86                     d[4] = c[4], d[5] = c[5];
 87                     for (k = 1; k <= 4; k ++) d[rot[i][k]] = c[rot[i][k - 1]];    
 88                 } else {
 89                     d[2] = c[2], d[3] = c[3];
 90                     for (k = 1; k <= 4; k ++) d[rot[i][k]] = c[rot[i][k - 1]];
 91                 }
 92                 int v = hash(d);
 93                 if (chk[v] == T) continue;
 94                 chk[v] = T;
 95                 que[en ++] = v; que[en ++] = dp + 1;
 96             }    
 97         }
 98         if (!bf) printf("-1\n");
 99     }
100     return 0;    
101 }
View Code

 

 

1008、Number Sequence

寻找题意特殊点:

我们会发现不论如何,最终的最大值都为(1+n)*n.

从另外一方面想,题目又与二进制有关,我们会发现,对于不超过2^k-1的数字,总能找到一个数字与其异或,结果为2^k-1.以此为线索进行贪心。

(这里注意贪心顺序,需要从大到小进行)

---注意一般10^5左右的复杂度都需要进行一次排序。

 1 //============================================================================
 2 // Name        : 20140920.cpp
 3 // Author      : 
 4 // Version     :
 5 // Copyright   : Your copyright notice
 6 // Description : Hello World in C++, Ansi-style
 7 //============================================================================
 8 
 9 #include <iostream>
10 #include <iostream>
11 #include <stdio.h>
12 #include <math.h>
13 #include <string.h>
14 #include <vector>
15 #include <algorithm>
16 using namespace std;
17 #define LL __int64
18 int f[100010],f1[100010];
19 int s[25] = {0};
20 
21 void init(){
22     int m = 2;
23     for(int i=0;i<25;i++){
24         s[i] = m-1;
25         m *= 2;
26     }
27 }
28 int Do(int n){
29     for(int i=0;i<25;i++) if(n==s[i]) return 1;
30     return 0;
31 }
32 int search(int x){
33     int i;
34     for(i=0;i<25;i++){
35         if(x > s[i]) continue;
36         else break;
37     }
38     return s[i];
39 }
40 int deal(int i){
41     int t = search(i);
42     int m = t - i;
43     f1[i] = m;
44     f1[m] = i;
45 }
46 int main() {
47     //freopen("in.txt", "r", stdin);
48     //freopen("out.txt","w",stdout);
49     int n;init();
50     while(scanf("%d",&n)!=EOF){
51         for(int i=0;i<=n;i++) {
52             scanf("%d",&f[i]);
53         }
54         printf("%I64d\n",(__int64)(n+1)*(n));
55         for(int i=0;i<=n;i++) f1[i] = -1;
56         int flag=1;
57         if(Do(n)) flag=0;  //flag = 1 时,0与n匹配,正常进行即可; 否则
58         else f1[0] = 0;
59         for(int i=n;i>=flag;i--){
60             if(f1[i]== -1) deal(i);
61         }
62         for(int i=0;i<=n;i++){
63             if(i) printf(" ");
64             printf("%d",f1[f[i]]);
65         }
66         printf("\n");
67     }
68     return 0;
69 }
View Code

 

1009、233 Matrix

技巧:矩阵快速幂、  

对于题目中有明显表示说的二维数据,如果两维相差比较大,一般会使用到矩阵快速幂

·10*10的矩阵,进行10^9次方单位的快速幂运算,大约3s。

  1 //============================================================================
  2 // Name        : 20140920.cpp
  3 // Author      : 
  4 // Version     :
  5 // Copyright   : Your copyright notice
  6 // Description : Hello World in C++, Ansi-style
  7 //============================================================================
  8 
  9 #include <iostream>
 10 #include <iostream>
 11 #include <stdio.h>
 12 #include <math.h>
 13 #include <string.h>
 14 #include <vector>
 15 #include <algorithm>
 16 using namespace std;
 17 #define Mod 10000007
 18 #define SMod Mod
 19 #define lll __int64
 20 #define LL __int64
 21 
 22 int n,m;
 23 lll a[100006],sum[100005];
 24 
 25 struct Matrix
 26 {
 27     lll m[13][13];
 28     Matrix()
 29     {
 30         memset(m,0,sizeof(m));
 31         for(int i=1;i<=n+2;i++)
 32             m[i][i] = 1LL;
 33     }
 34 };
 35 
 36 Matrix Mul(Matrix a,Matrix b)
 37 {
 38     Matrix res;
 39     int i,j,k;
 40     for(i=1;i<=n+2;i++)
 41     {
 42         for(j=1;j<=n+2;j++)
 43         {
 44             res.m[i][j] = 0;
 45             for(k=1;k<=n+2;k++)
 46                 res.m[i][j] = (res.m[i][j]+(a.m[i][k]*b.m[k][j])%SMod + SMod)%SMod;
 47         }
 48     }
 49     return res;
 50 }
 51 
 52 Matrix fastm(Matrix a,int b)  //返回a^b次方
 53 {
 54     Matrix res;
 55     while(b)
 56     {
 57         if(b&1)
 58             res = Mul(res,a);
 59         a = Mul(a,a);
 60         b >>= 1;
 61     }
 62     return res;
 63 }
 64 
 65 int main()
 66 {
 67     freopen("in.txt", "r", stdin);
 68     //freopen("out.txt","w",stdout);
 69     int i,j;
 70     while(scanf("%d%d",&n,&m)!=EOF)
 71     {
 72         sum[0] = 0;
 73         for(i=1;i<=n;i++)
 74         {
 75             scanf("%I64d",&a[i]);  //第一列的数字
 76             sum[i] = (sum[i-1] + a[i]);
 77         }
 78         lll suma = sum[n];
 79         if(m == 1)
 80         {
 81             printf("%I64d\n",(233LL+suma)%Mod);
 82             continue;
 83         }
 84 
 85         Matrix base;
 86         memset(base.m,0,sizeof(base.m));
 87         for(i=1;i<=n+1;i++)  // 这里n最大为10,  m开到了[13][13],(0位置没有用)
 88             base.m[i][1] = 10LL;
 89         for(i=2;i<=n+1;i++)
 90         {
 91             for(j=2;j<=n+1;j++)
 92             {
 93                 if(i >= j)
 94                     base.m[i][j] = 1LL;
 95             }
 96         }
 97         for(i=1;i<=n+2;i++)
 98             base.m[i][n+2] = 1LL;
 99         //初始化需要进行快速幂的矩阵!
100 
101         Matrix Right;
102         memset(Right.m,0,sizeof(Right.m));
103         Right.m[1][1] = 233LL;
104         for(i=2;i<=n+1;i++)
105             Right.m[i][1] = (233LL+sum[i-1])%Mod;  //构造第一列的数据,之后后面进行m-1次的矩阵快速幂
106         Right.m[n+2][1] = 3LL;
107 
108         Matrix ans = fastm(base,m-1);
109         ans = Mul(ans,Right);
110         printf("%I64d\n",ans.m[n+1][1]%Mod);
111     }
112     return 0;
113 }
View Code

·注意矩阵构造的方法,这点是难点。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值