1. 程式人生 > >2016百度之星 資格賽ABCDE

2016百度之星 資格賽ABCDE

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
            
           

相關推薦

2016 資格賽ABCDE

A.題意:定義小寫字母組成的字串的雜湊值,為(單個字母的ASCII碼減去28)的乘積。給出長度最多為100000的字串和最多1000次詢問,每次詢問[L,R]之間的字串的雜湊值。 題解: 有多種做法。 1.逆元  2.線段樹  3.分塊陣列 1.逆元做法:因為每次求區間[L,R]乘積,可以

2016 - 資格賽 Astar Round1 - 模擬+線段樹+乘法逆元

                Problem A   Accepts:

2016資格賽題解

1 #include<stdio.h> 2 #include<string.h> 3 #include<map> 4 #include<string> 5 using namespace std; 6 7 struc

ACM-資格賽Energy Conversion——hdu4823

ios break get enter span bmi ria hint -c Energy Conversion Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Jav

2014資格賽題解

.cn -i lan while pro acm 起點 pos con 比賽鏈接:點擊打開鏈接 ,,杭電把比賽關了代碼都找不到了。。 無責任民科還是mark一下好了。。 HDU 4823 Energy Conversion 把式子變換一下發現是一個等比數列,高速冪就可以

2014資格賽第三題

字符串 struct uri hit other printf 能夠 ava 單獨 Xor Sum Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 132768/132768 K (Java/Others

2014資格賽4題

歐幾裏得 font define ria min read span post eight 因為都是中文題。題意就不寫了。 A、Energy Conversion 這題先推斷一下能量能否添加,然後再依據添加這個公式去求出一個等比公式。就能夠直接求出須

2017資格賽 1003:度度熊與邪惡大魔王(DP)

solution nav normal ner 就會 預處理 display badge rate 度度熊與邪惡大魔王 Accepts: 3021 Submissions: 18787 Time Limit: 2000/1000 MS (Java/Ot

2017資格賽 1003 度度熊與邪惡大魔王 背包DP

log accep 防禦 ssi str 完全背包 time 怪物 amp 度度熊與邪惡大魔王 Accepts: 3027 Submissions: 18837 Time Limit: 2000/1000 MS (Java/Others) Memor

度度熊的午飯時光 2017資格賽 -.-

set others spa 字典序 info iostream 最小 long long 預算 度度熊的午飯時光 Accepts: 755 Submissions: 8737 Time Limit: 2000/1000 MS (Java/Others)

2017 資格賽 題解

真心 數據 targe 比較 blog png 防禦 href 普通 百度之星 2017 資格賽 題解(原創)(2~5題 第一題方法是錯的 第二題數據太水 並不會正解) 轉載請註明出處http://www.cnblogs.com/nflslzt/p/7302377.html

【2018資格賽】 A 問卷調查 - 位運算&動規

blog 題目 相同 clas 方程 數組 cstring div col 題目地址:http://bestcoder.hdu.edu.cn/contests/contest_showproblem.php?cid=820&pid=1001 參考博客:在此感謝ht

2018資格賽 1001調查問卷(狀壓dp)

百度之星 一行 problem nts 數據 output 兩張 href bestcode 調查問卷 Accepts: 1289 Submissions: 5642 Time Limit: 6500/6000 MS (Java/Others

2018 資格賽 1001 調查問卷

題目連結:http://acm.hdu.edu.cn/showproblem.php?pid=6344 題意:給n份問卷,每個問卷m道題,每題只有A,B兩種選項,問存在多少個問題集合,使得只保留這些問題後至少k對卷子不同。  題解:剛開始做的時候,沒有什麼思路,因為要求至少K對

2018資格賽___1001調查問卷——狀態壓縮

補題連結:傳送門 題目大意:   有TTT組樣例,nnn份問卷,每份問卷有mmm個問題,答案由A或B組成(相當於nnn條長度為mmm的01序列),在這mmm個問題中任意選取一部分,要使這新的零散問卷互不相同,且至少有k對,問這樣選取一共有多少種方案??? 解題思

2017資格賽題解

度度熊為了拯救可愛的公主,於是與邪惡大魔王戰鬥起來。 邪惡大魔王的麾下有n個怪獸,每個怪獸有a[i]的生命值,以及b[i]的防禦力。 度度熊一共擁有m種攻擊方式,第i種攻擊方式,需要消耗k[i]的晶石,造成p[i]點傷害。 當然,如果度度熊使用第i個技能打在第j個怪獸上面的話,會使得第j個怪獸的生命值減少p

2016 初賽2A ABEF

只做了1001 1002 1005 1006。剩下2題可能以後補? http://acm.hdu.edu.cn/search.php?field=problem&key=2016%22%B0%D9%B6%C8%D6%AE%D0%C7%22+-+%B3%F5%C8%FC%A3%A8Astar+Roun

2016 初賽2B ACEF

做了1001 1003 1005 1006 1001 區間的價值 亂搞? 做法簡介:有多種做法,主要思想都是先算a[i]作為最小值能管轄的最大左右範圍l[i], r[i],然後求[ l[i], r[i] ]區間內的最大值ma,判斷是否可以更新ans[r[i] - l[i] + 1] = ma

2016複賽 1003 拍照 優先佇列

2016"百度之星" - 複賽(Astar Round3)  Ended  2016-05-29 14:00:00 - 2016-05-29 17:00:00 Current Time: 00:46:02 SolvedPro.IDTitleRatio(Accepted / Submi

資格賽】F:百科蝌蚪團

時間限制: 1000ms 記憶體限制: 65536kB 描述 百度百科有一支神奇的隊伍,他們叫自己“百科蝌蚪團”。為了更好的讓蝌蚪團的成員們安排工作,百度百科的運營團隊定出了一個24小時制的時間表。例如: 1. 每個蝌蚪團成員工作時長相同; 2. 必須安排蝌蚪團成員在