2016百度之星 资格赛ABCDE

看题:http://bestcoder.hdu.edu.cn/contests/contest_show.php?cid=690

交题:http://acm.hdu.edu.cn/search.php?field=problem&key=2016%22%B0%D9%B6%C8%D6%AE%D0%C7%22+-+%D7%CA%B8%F1%C8%FC%A3%A8Astar+Round1%A3%A9&source=1&searchmode=source

Solved Pro.ID Title Author Source (AC/Submit)Ratio
You has solved this problem :-) 5685 Problem A   2016"百度之星" - 资格赛(Astar Round1) (215/533)40.34%
You has solved this problem :-) 5686 Problem B   2016"百度之星" - 资格赛(Astar Round1) (150/424)35.38%
You has solved this problem :-) 5687 Problem C   2016"百度之星" - 资格赛(Astar Round1) (187/532)35.15%
You has solved this problem :-) 5688 Problem D   2016"百度之星" - 资格赛(Astar Round1) (226/315)71.75%
You has solved this problem :-) 5689 Problem E   2016"百度之星" - 资格赛(Astar Round1) (36/72)50.00%

A.题意:定义小写字母组成的字符串的哈希值,为(单个字母的ASCII码减去28)的乘积。给出长度最多为100000的字符串和最多1000次询问,每次询问[L,R]之间的字符串的哈希值。

题解:

有多种做法。

1.逆元  2.线段树  3.分块数组

1.逆元做法:因为每次求区间[L,R]乘积,可以用[1,R]乘([1,L-1]的逆元),就用预处理前缀积、前缀积逆元来搞,O(1)查询。好像代码写起来最简单。

2.线段树、块状数组做法:就做啊。线段树O(log(n))查询

我的是块状数组的,分sqrt大块,预处理大块,O(sqrt(n))查询,不是很推荐。

代码:

  1 //#pragma comment(linker, "/STACK:102400000,102400000")
  2 #include<cstdio>
  3 #include<cmath>
  4 #include<iostream>
  5 #include<cstring>
  6 #include<algorithm>
  7 #include<cmath>
  8 #include<map>
  9 #include<set>
 10 #include<stack>
 11 #include<queue>
 12 using namespace std;
 13 
 14 #define MZ(array) memset(array, 0, sizeof(array))
 15 #define MF1(array) memset(array, -1, sizeof(array))
 16 #define MINF(array) memset(array, 0x3f, sizeof(array))
 17 #define REP(i,n) for(i=0;i<(n);i++)
 18 #define FOR(i,x,n) for(i=(x);i<=(n);i++)
 19 #define FORD(i,x,y) for(i=(x);i>=(y);i--)
 20 #define RD(x) scanf("%d",&x)
 21 #define RD2(x,y) scanf("%d%d",&x,&y)
 22 #define RD3(x,y,z) scanf("%d%d%d",&x,&y,&z)
 23 #define WN(x) printf("%d\n",x);
 24 #define RE  freopen("D.in","r",stdin)
 25 #define WE  freopen("huzhi.txt","w",stdout)
 26 #define MP make_pair
 27 #define PB push_back
 28 #define PF push_front
 29 #define PPF pop_front
 30 #define PPB pop_back
 31 typedef long long LL;
 32 typedef unsigned long long ULL;
 33 
 34 const double PI=acos(-1.0);
 35 const double EPS=1e-10;
 36 const int MAXN=1111;
 37 const int MOD=9973;
 38 int n;
 39 int a[MAXN],b[MAXN];
 40 char s[111111];
 41 int l;
 42 
 43 int q[111111];
 44 int ql;
 45 
 46 void init() {
 47     int i,j;
 48     ql=sqrt(l);
 49     int qll = l/ql;
 50     REP(i,qll) {
 51         q[i]=1;
 52         int ed = (i+1)*ql - 1;
 53         FOR(j,i*ql,ed) {
 54             q[i]*=s[j];
 55             q[i]%=MOD;
 56         }
 57     }
 58 }
 59 
 60 int gank(int a,int b) {
 61     if(a==b)return s[a];
 62     int sti=ceil(1.0*a/ql), edi=b/ql;
 63     int st = sti*ql;
 64     int ed = edi*ql;
 65     int i;
 66     int re=1;
 67     if(ed<st) {
 68         FOR(i,a,b) {
 69             re*=s[i];
 70             re%=MOD;
 71         }
 72     } else {
 73         FOR(i,a,st-1) {
 74             re*=s[i];
 75             re%=MOD;
 76         }
 77         FOR(i,sti,edi-1) {
 78             re*=q[i];
 79             re%=MOD;
 80         }
 81         FOR(i,ed,b) {
 82             re*=s[i];
 83             re%=MOD;
 84         }
 85     }
 86     return re;
 87 }
 88 
 89 int farm() {
 90     int i;
 91     l=strlen(s);
 92     REP(i,l)s[i]-=28;
 93     init();
 94     REP(i,n) {
 95         WN(gank(a[i], b[i]));
 96     }
 97 }
 98 
 99 int main() {
100     int i;
101     while(RD(n)!=EOF) {
102         scanf(" %s",s);
103         REP(i,n) {
104             RD2(a[i],b[i]);
105             a[i]--;
106             b[i]--;
107         }
108         farm();
109     }
110     return 0;
111 }
View Code

 

B.定义全1序列,其中任意2个1可以组成1个2。给出1的数量(N<=200),求可以组成多少不同的序列。

题解:

找规律,或者推出规律。

设n个1组成的不同序列数量为a[n],可以得知规律:

a[n] = a[n-1] + a[n-2]

相当于n-2的序列后面跟个2,n-1的序列后面跟个1。

注意,从公式可以看出,最后答案大上天,比2^200大,用java的BigInteger搞。

代码:

 1 import java.io.BufferedReader;
 2 import java.io.IOException;
 3 import java.io.InputStreamReader;
 4 import java.io.OutputStreamWriter;
 5 import java.io.PrintWriter;
 6 import java.io.StreamTokenizer;
 7 import java.math.BigInteger;
 8 
 9 public class Main {
10 
11     private static final int MAXN = 11111;
12 
13     private static final StreamTokenizer in = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
14     private static final PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
15 
16     private static int RD(StreamTokenizer in) throws IOException {
17         in.nextToken();
18         return (int) in.nval;
19     }
20 
21     public static BigInteger gank(int x){
22         BigInteger[] a = new BigInteger[x+5];
23         a[1]=BigInteger.ONE;
24         a[2]=BigInteger.ONE.add(BigInteger.ONE);
25         for(int i=3; i<=x; i++){
26             a[i]=a[i-1].add(a[i-2]);
27         }
28         return a[x];
29     }
30     
31     public static void main(String[] args) throws IOException {
32         while (in.nextToken() != StreamTokenizer.TT_EOF) {
33             int n = (int) in.nval;
34             out.println(gank(n));
35 //            for (int i = 0; i < n; i++) {
36 //                int x = RD(in);
37 ////                ma = Math.max(ma, x);
38 //                out.println(gank(x));
39 //            }
40 
41 //            out.printf("%s\n", ans);
42             out.flush();
43         }
44     }
45 
46 }
View Code

 

C.题面:

度熊手上有一本神奇的字典,你可以在它里面做如下三个操作:

1、insert : 往神奇字典中插入一个单词
2、delete: 在神奇字典中删除所有前缀等于给定字符串的单词
3、search: 查询是否在神奇字典中有一个字符串的前缀等于给定的字符串

10W个操作,字符串长度不超过30。

题解:

可以看出这是Trie树题,不过有一般Trie树题没有的删除操作。注意删除时找到那个节点,得到通过节点的字符串数x, 然后子树也要处理,到根的路径也要处理。

子树可以删掉,也可以字符串数清零。到根的路径每个点减去x。

代码:

  1 //#pragma comment(linker, "/STACK:102400000,102400000")
  2 #include<cstdio>
  3 #include<cmath>
  4 #include<iostream>
  5 #include<cstring>
  6 #include<algorithm>
  7 #include<cmath>
  8 #include<map>
  9 #include<set>
 10 #include<stack>
 11 #include<queue>
 12 using namespace std;
 13 
 14 #define MZ(array) memset(array, 0, sizeof(array))
 15 #define MF1(array) memset(array, -1, sizeof(array))
 16 #define MINF(array) memset(array, 0x3f, sizeof(array))
 17 #define REP(i,n) for(i=0;i<(n);i++)
 18 #define FOR(i,x,n) for(i=(x);i<=(n);i++)
 19 #define FORD(i,x,y) for(i=(x);i>=(y);i--)
 20 #define RD(x) scanf("%d",&x)
 21 #define RD2(x,y) scanf("%d%d",&x,&y)
 22 #define RD3(x,y,z) scanf("%d%d%d",&x,&y,&z)
 23 #define WN(x) printf("%d\n",x);
 24 #define RE  freopen("D.in","r",stdin)
 25 #define WE  freopen("huzhi.txt","w",stdout)
 26 #define MP make_pair
 27 #define PB push_back
 28 #define PF push_front
 29 #define PPF pop_front
 30 #define PPB pop_back
 31 typedef long long LL;
 32 typedef unsigned long long ULL;
 33 
 34 const double PI=acos(-1.0);
 35 const double EPS=1e-10;
 36 const int MAXN=111111;
 37 const int MAXM=33;
 38 
 39 class Trie{
 40 public:
 41     Trie* a[26];
 42     int n;
 43     Trie(){
 44         int i;
 45         REP(i,26)a[i]=NULL;
 46         n=0;
 47     }
 48 };
 49 
 50 Trie root;
 51 
 52 inline void ins(char s[MAXM]) {
 53     int l=strlen(s);
 54     int i,j;
 55     Trie *pre = &root;
 56     REP(i,l) {
 57         int c = s[i] - 'a';
 58         Trie *x = pre->a[c];
 59         if(x==NULL) {
 60             pre->a[c] = new Trie();
 61             x = pre->a[c];
 62         }
 63         pre->n++;
 64         pre=x;
 65     }
 66     pre->n++;
 67 }
 68 
 69 inline Trie* sch(char s[MAXM]) {
 70     int l=strlen(s);
 71     int i;
 72     Trie *x = &root;
 73     REP(i,l) {
 74         int c = s[i]-'a';
 75         x = x->a[c];
 76         if(x==NULL || x->n<=0)return NULL;
 77     }
 78     return x;
 79 }
 80 
 81 inline void delSon(Trie *x){
 82     int i;
 83     if(x->n<=0)return;
 84     REP(i,26)if(x->a[i]!=NULL){
 85         delSon(x->a[i]);
 86     }
 87 //    delete(x);
 88     x->n=0;
 89 }
 90 
 91 inline int del(const int &now, const int &l ,Trie *x, char s[MAXM]) {
 92     char c = s[now]-'a';
 93     Trie *w = x->a[c];
 94     if(w==NULL || w->n<=0)return 0;
 95     if(now==l-1){
 96         int n = w->n;
 97 //        x->a[c]=NULL;
 98         delSon(w);
 99         return n;
100     }
101     w->n -= del(now+1, l, w, s);
102 }
103 
104 int main() {
105     int i,n;
106     char c[MAXM],s[MAXM];
107     RD(n);
108     root = Trie();
109     REP(i,n) {
110         scanf(" %s %s",c,s);
111         if(c[0]=='i')ins(s);
112         else if(c[0]=='d')del(0,strlen(s),&root,s);
113         else {
114             if(sch(s)!=NULL) puts("Yes");
115             else puts("No");
116         }
117     }
118     return 0;
119 }
View Code

 

D.定义某国人名:人名中的任意字母换位置,还是指同一个人。输入10W个人名,对每次输入输出这个人之前出现过多少次。

题解:

对每个人名排序一下再加入map里,随便统计。

代码:

 1 //#pragma comment(linker, "/STACK:102400000,102400000")
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<iostream>
 5 #include<cstring>
 6 #include<algorithm>
 7 #include<cmath>
 8 #include<map>
 9 #include<set>
10 #include<stack>
11 #include<queue>
12 using namespace std;
13 
14 #define MZ(array) memset(array, 0, sizeof(array))
15 #define MF1(array) memset(array, -1, sizeof(array))
16 #define MINF(array) memset(array, 0x3f, sizeof(array))
17 #define REP(i,n) for(i=0;i<(n);i++)
18 #define FOR(i,x,n) for(i=(x);i<=(n);i++)
19 #define FORD(i,x,y) for(i=(x);i>=(y);i--)
20 #define RD(x) scanf("%d",&x)
21 #define RD2(x,y) scanf("%d%d",&x,&y)
22 #define RD3(x,y,z) scanf("%d%d%d",&x,&y,&z)
23 #define WN(x) printf("%d\n",x);
24 #define RE  freopen("D.in","r",stdin)
25 #define WE  freopen("huzhi.txt","w",stdout)
26 #define MP make_pair
27 #define PB push_back
28 #define PF push_front
29 #define PPF pop_front
30 #define PPB pop_back
31 typedef long long LL;
32 typedef unsigned long long ULL;
33 
34 const double PI=acos(-1.0);
35 const double EPS=1e-10;
36 const int MAXN=1000044;
37 
38 int n;
39 map<string,int> q;
40 
41 
42 int main(){
43     int i;
44     char s[55];
45     RD(n);
46     REP(i,n){
47         scanf(" %s",s);
48         int l = strlen(s);
49         sort(s,s+l);
50         string st = s;
51         WN(q[st]);
52         q[st]++;
53     }
54     return 0;
55 }
View Code

 

E.题面说得超不清楚,根本不可能看懂,所以第一天只有一点点人过这题。我写一下根据Clarify中的参赛者讨论得到的题面:

样例输入:
4
a < 100
c > 99
b > 100 , b == 99 , c < 98
a < 1000, a >= 99
样例输出:
unique
1
unique
1 2

其中第一个数N为下面的行数,最多1000。各种变量名最长30。

对于每行输入,输出上面有哪些行与它给出的范围有交集。

例如第二行的c>99,因为第一行没有规定c的范围,相当于c是[-无限,+无限],第二行没有规定a的范围,所以(第一行)交(第二行)不为空。

第三行的b有冲突,是个空集,所以它和谁都不交。

第四行的确和第一行、第二行交。

还有个没说的地方是这个只看整数,a>99, a<100是空集。

 

题解:

可以看出每行对于每个变量只有一个区间,就暴力模拟就行了。

代码:

  1 //#pragma comment(linker, "/STACK:102400000,102400000")
  2 #include<cstdio>
  3 #include<cmath>
  4 #include<iostream>
  5 #include<cstring>
  6 #include<algorithm>
  7 #include<cmath>
  8 #include<map>
  9 #include<set>
 10 #include<stack>
 11 #include<queue>
 12 using namespace std;
 13 
 14 #define MZ(array) memset(array, 0, sizeof(array))
 15 #define MF1(array) memset(array, -1, sizeof(array))
 16 #define MINF(array) memset(array, 0x3f, sizeof(array))
 17 #define REP(i,n) for(i=0;i<(n);i++)
 18 #define FOR(i,x,n) for(i=(x);i<=(n);i++)
 19 #define FORD(i,x,y) for(i=(x);i>=(y);i--)
 20 #define RD(x) scanf("%d",&x)
 21 #define RD2(x,y) scanf("%d%d",&x,&y)
 22 #define RD3(x,y,z) scanf("%d%d%d",&x,&y,&z)
 23 #define WN(x) printf("%d\n",x);
 24 #define RE  freopen("1.in","r",stdin)
 25 #define WE  freopen("huzhi.txt","w",stdout)
 26 #define MP make_pair
 27 #define PB push_back
 28 #define PF push_front
 29 #define PPF pop_front
 30 #define PPB pop_back
 31 typedef long long LL;
 32 typedef unsigned long long ULL;
 33 
 34 const double PI=acos(-1.0);
 35 const double EPS=1e-10;
 36 const int MAXN=1111;
 37 const int MAXM=33;
 38 
 39 char w[MAXN][MAXM];
 40 int wn;
 41 int q[MAXN];
 42 int qn;
 43 
 44 int n;
 45 int L[MAXN][MAXM];
 46 int R[MAXN][MAXM];
 47 bool isPig[MAXN];
 48 
 49 map<string, int>mp;
 50 int xn;
 51 void add(int k, char xx[MAXM], char oo[MAXM], int yy) {
 52     string name = xx;
 53     if(mp.find(name)==mp.end())mp[name] = xn++;
 54     int x = mp[name];
 55 
 56     if(oo[0]=='<') {
 57         if(oo[1]=='=') R[k][x] = min(R[k][x], yy);
 58         else R[k][x] = min(R[k][x], yy - 1);
 59     } else if(oo[0]=='>') {
 60         if(oo[1]=='=') L[k][x] = max(L[k][x], yy);
 61         else L[k][x] = max(L[k][x], yy + 1);
 62     } else {
 63         L[k][x] = max(L[k][x], yy);
 64         R[k][x] = min(R[k][x], yy);
 65     }
 66     if(L[k][x]>R[k][x])isPig[k]=1;
 67 }
 68 
 69 void saveTheEquals() {
 70     int i,j,k;
 71     mp.clear();
 72     xn=0;
 73     MZ(isPig);
 74     REP(i,n) REP(j,30) {
 75         L[i][j]=-20000;
 76         R[i][j]=20000;
 77     }
 78     i=0;
 79     j=0;
 80     k=0;
 81     while(i<wn) {
 82         if(!isPig[k])add(k,w[i],w[i+1],q[j]);
 83         j++;
 84         if(w[i+2][0]!=',') {
 85             k++;
 86             i+=2;
 87         } else i+=3;
 88     }
 89 }
 90 
 91 inline bool banana(const int &x,const int &y,const int &k) {
 92     int &L1 = L[x][k];
 93     int &R1 = R[x][k];
 94     int &L2 = L[y][k];
 95     int &R2 = R[y][k];
 96     if(L1<=L2 && L2<=R1)return true;
 97     if(L2<=L1 && L1<=R2)return true;
 98     return false;
 99 }
100 
101 void farm() {
102     int i,j,k;
103     REP(i,n) {
104         vector<int>v;
105         v.clear();
106         if(!isPig[i]) {
107             REP(j,i) {
108                 bool ok=true;
109                 if(isPig[j])continue;
110                 REP(k,xn) {
111                     if(!banana(i,j,k)) {
112                         ok=false;
113                         break;
114                     }
115                 }
116                 if(ok) {
117                     v.push_back(j+1);
118                 }
119             }
120         }
121         if(v.size()==0) {
122             puts("unique");
123         } else {
124             printf("%d",v[0]);
125             for(j=1; j<v.size(); j++)
126                 printf(" %d",v[j]);
127             puts("");
128         }
129     }
130 }
131 
132 int main() {
133 //    RE;
134     int i,j;
135     char s[MAXM];
136     char line[MAXN];
137     RD(n);
138     wn=0;
139     qn=0;
140     while(scanf(" %s",s)!=EOF) {
141         strcpy(w[wn],s);
142         wn++;
143         if(s[0]!=',') {
144             scanf(" %s %d",w[wn], &q[qn]);
145             wn++;
146             qn++;
147         }
148     }
149     saveTheEquals();
150     farm();
151     return 0;
152 }
View Code

 

posted @ 2016-05-23 20:15  带鱼Yuiffy  阅读(340)  评论(0编辑  收藏  举报