日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

全国信息学奥林匹克联赛 ( NOIP2014) 复赛 模拟题 Day1 长乐一中

發(fā)布時(shí)間:2024/8/26 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 全国信息学奥林匹克联赛 ( NOIP2014) 复赛 模拟题 Day1 长乐一中 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
題目名稱正確答案?序列問題長(zhǎng)途旅行
英文名稱answersequencetravel
輸入文件名answer.insequence.intravel.in
輸出文件名answer.outsequence.outtravel.out
時(shí)間限制1s1s1s
空間限制? 256M256M256M
測(cè)試點(diǎn)數(shù)目202010
測(cè)試點(diǎn)分值5510
是否有部分分
題目類型傳統(tǒng)傳統(tǒng)傳統(tǒng)
是否有 SPJ

?

正確答案 全國(guó)信息學(xué)奧林匹克聯(lián)賽( ( NOIP2014) 復(fù) 賽 模擬題 Day1 長(zhǎng)樂一中

【題目描述】
小 H 與小 Y 剛剛參加完 UOIP 外卡組的初賽,就迫不及待的跑出考場(chǎng)對(duì)答案。
“吔,我的答案和你都不一樣!”,小 Y 說道,”我們?nèi)フ疑駹膫儐柎鸢赴伞薄?br />外卡組試卷中共有 m 道判斷題,小 H 與小 Y 一共從其他 n 個(gè)神犇那問了答案。之后又
從小 G 那里得知, 這 n 個(gè)神犇中有 p 個(gè)考了滿分, q 個(gè)考了零分, 其他神犇不為滿分或零分。
這可讓小 Y 與小 H 犯了難。你能幫助他們還原出標(biāo)準(zhǔn)答案嗎?如有多解則輸出字典序最小
的那個(gè)。無解輸出-1。
【 輸入格式】
第一行四個(gè)整數(shù) n, m, p, q,意義如上描述。
接下來 n 行,每一行 m 個(gè)字符’N’或’Y’,表示這題這個(gè)神犇的答案。
【 輸出格式】
僅一行,一個(gè)長(zhǎng)度為 m 的字符串或是-1。
【 樣例輸入】
2 2 2 0
YY
YY
【 樣例輸出】
YY
【 數(shù)據(jù)范圍】
30% : n <= 100.
60% : n <= 5000 , m <= 100.
100% : 1 <= n <= 30000 , 1 <= m <= 500. 0 <= p , q 且 p + q <= n.

T1:
30%: O(n ^ 2 * m)暴力判斷。
100%: 很顯然答案的可能性最多只有 n 種,所以我們將所有人的答案按字典序排序后枚舉
將每個(gè)人的答案作為正確答案來進(jìn)行判斷。 由于是判斷題, 若當(dāng)前人的答案為正確答
案則零分者的答案也就確定了, 那么只需統(tǒng)計(jì)出這兩種答案的人數(shù)判斷是否滿足題意
即可。這一步使用字符串哈希即可解決。
另外要注意 p = 0 和 p = q = 0 的情況。

1 #include <algorithm> 2 #include <iostream> 3 #include <cstring> 4 #include <cstdio> 5 #include <cmath> 6 using namespace std; 7 8 const int N = 3e4 + 2, M = 5e2 + 2, sed = 31, SED = 131, mod = 70177, MOD = 92311; 9 int n, m, p, q, ans, hash[N], HASH[N]; 10 int top, info[mod], nxt[N * 2], fet[N * 2], cnt[N * 2]; 11 struct node { 12 char s[M]; 13 inline bool operator < (const node &b) const { 14 return strcmp(s, b.s) < 0; 15 } 16 } a[N]; 17 18 inline void Insert(const int &x, const int &y) { 19 for (int k = info[x]; k; k = nxt[k]) 20 if (fet[k] == y) { 21 ++cnt[k]; return ; 22 } 23 nxt[++top] = info[x]; info[x] = top; 24 fet[top] = y; cnt[top] = 1; 25 return ; 26 } 27 28 inline int Query(const int &x, const int &y) { 29 for (int k = info[x]; k; k = nxt[k]) 30 if (fet[k] == y) return cnt[k]; 31 return 0; 32 } 33 34 inline void Solve1() { 35 int tmp, TMP; ans = -1; 36 for (int i = 0; i < n; ++i) { 37 tmp = TMP = 0; 38 for (int j = 0; j < m; ++j) { 39 tmp = (tmp * sed + (a[i].s[j] == 'N')) % mod; 40 TMP = (TMP * SED + (a[i].s[j] == 'N')) % MOD; 41 } 42 hash[i] = tmp, HASH[i] = TMP; 43 Insert(tmp, TMP); 44 } 45 for (int i = 0; i < n; ++i) 46 if (Query(hash[i], HASH[i]) == p) { 47 tmp = TMP = 0; 48 for (int j = 0; j < m; ++j) { 49 tmp = (tmp * sed + (a[i].s[j] == 'Y')) % mod; 50 TMP = (TMP * SED + (a[i].s[j] == 'Y')) % MOD; 51 } 52 if (Query(tmp, TMP) == q) { 53 ans = i; break; 54 } 55 } 56 if (ans != -1) printf("%s\n", a[ans].s); 57 else puts("-1"); 58 return ; 59 } 60 61 char cur[M]; 62 inline void Solve2() { 63 int tmp, TMP; ans = -1; 64 for (int i = 0; i < n; ++i) { 65 tmp = TMP = 0; 66 for (int j = 0; j < m; ++j) { 67 tmp = (tmp * sed + (a[i].s[j] == 'N')) % mod; 68 TMP = (TMP * SED + (a[i].s[j] == 'N')) % MOD; 69 } 70 hash[i] = tmp, HASH[i] = TMP; 71 Insert(tmp, TMP); 72 } 73 for (int i = n - 1; i >= 0; --i) 74 if (Query(hash[i], HASH[i]) == q) { 75 tmp = TMP = 0; 76 for (int j = 0; j < m; ++j) { 77 tmp = (tmp * sed + (a[i].s[j] == 'Y')) % mod; 78 TMP = (TMP * SED + (a[i].s[j] == 'Y')) % MOD; 79 } 80 if (Query(tmp, TMP) == p) { 81 ans = i; break; 82 } 83 } 84 if (ans != -1) { 85 for (int i = 0; i < m; ++i) 86 cur[i] = a[ans].s[i] == 'N' ? 'Y' : 'N'; 87 printf("%s\n", cur); 88 } 89 else puts("-1"); 90 return ; 91 } 92 93 void Solve3() { 94 int tmp, TMP; 95 for (int i = 0; i < n; ++i) { 96 tmp = TMP = 0; 97 for (int j = 0; j < m; ++j) { 98 tmp = (tmp * sed + (a[i].s[j] == 'N')) % mod; 99 TMP = (TMP * SED + (a[i].s[j] == 'N')) % MOD; 100 } 101 Insert(tmp, TMP); 102 tmp = TMP = 0; 103 for (int j = 0; j < m; ++j) { 104 tmp = (tmp * sed + (a[i].s[j] == 'Y')) % mod; 105 TMP = (TMP * SED + (a[i].s[j] == 'Y')) % MOD; 106 } 107 Insert(tmp, TMP); 108 } 109 bool flag = true; 110 for (int i = 0; i < m; ++i) cur[i] = 'N'; 111 do { 112 tmp = TMP = 0; 113 for (int j = 0; j < m; ++j) { 114 tmp = (tmp * sed + (cur[j] == 'N')) % mod; 115 TMP = (TMP * SED + (cur[j] == 'N')) % MOD; 116 } 117 if (Query(tmp, TMP) == 0) { 118 flag = true; break; 119 } 120 flag = false; 121 for (int j = m - 1; j >= 0; --j) 122 if (cur[j] == 'Y') cur[j] = 'N'; 123 else { 124 cur[j] = 'Y'; flag = true; break; 125 } 126 } while (flag); 127 if (flag) printf("%s\n", cur); 128 else puts("-1"); 129 return ; 130 } 131 132 int main() { 133 freopen("answer.in", "r", stdin); 134 freopen("answer.out", "w", stdout); 135 scanf("%d%d%d%d", &n, &m, &p, &q); 136 for (int i = 0; i < n; ++i) scanf("%s", a[i].s); 137 sort(a, a + n); 138 if (p) Solve1(); 139 else if (q) Solve2(); 140 else Solve3(); 141 fclose(stdin); fclose(stdout); 142 return 0; 143 } View Code

2. 序列問題
【 題目描述】
小 H 是個(gè)善于思考的學(xué)生,她正在思考一個(gè)有關(guān)序列的問題。
她的面前浮現(xiàn)出了一個(gè)長(zhǎng)度為 n 的序列{ai},她想找出兩個(gè)非空的集合 S、T。
這兩個(gè)集合要滿足以下的條件:
1. 兩個(gè)集合中的元素都為整數(shù),且都在 [1, n] 里,即 Si,Ti ∈ [1, n]。
2. 對(duì)于集合 S 中任意一個(gè)元素 x,集合 T 中任意一個(gè)元素 y,滿足 x < y。
3. 對(duì)于大小分別為 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 想知道一共有多少對(duì)這樣的集合(S,T),你能幫助她嗎?
【輸入格式】
第一行,一個(gè)整數(shù) n
第二行,n 個(gè)整數(shù),代表 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 (&為與運(yùn)算)
S = {3}, T = {4} 3 = 3 = 3
【 數(shù)據(jù)范圍】
30%: 1 <= n <= 10
60%: 1 <= n <= 100
100%: 1 <= n <= 1000, 0 <= ai < 1024

T2:
30%:枚舉每個(gè)數(shù)所在的集合或者不選,然后判定即可。復(fù)雜度 O(n*3^n)。
60%: Dp, 兩個(gè)數(shù)相等就相當(dāng)于兩個(gè)數(shù)的 xor 為 0。 設(shè) f[i][j][k=0..2]代表 處理到第 I 個(gè)數(shù),
如果 k = 1 代表 and 值為 j,如果 k = 2 代表 xor 值為 j,如果 k = 0 則代表一個(gè)元素都沒
取。所以很容易得到方程:
f[i][j][0] = f[i + 1][j][0]
f[i][j & ai][1] = f[i + 1][j][1] + f[i + 1][j][0] + f[i + 1][j & ai][1]
f[i][j ^ ai][2] = f[i + 1][j][1] + f[i + 1][j][2] + f[i + 1][j ^ ai][2];
最后 f[1][0][2]就是答案, 復(fù)雜度為 O(n * 1024 * 3)
DP 還可以分開用 f[i][j]和 g[i][j]表示前 i 個(gè) xor 值為 j,后 i 個(gè) and 值為 j 的方案數(shù),
隨后枚舉分界點(diǎn) k 來求總方案數(shù)。復(fù)雜度 O(n * 1024 * 3)。
100%:滿分?jǐn)?shù)據(jù)需要高精,答案位數(shù)較大,需要進(jìn)行壓位來防止 TLE,因?yàn)椴恢来鸢傅?br />位數(shù)究竟多大,壓位后高精數(shù)組仍需要開的較大一些,所以原 DP 的數(shù)組滾動(dòng)即可。

1 #include <algorithm> 2 #include <iostream> 3 #include <cstring> 4 #include <cstdio> 5 #include <cmath> 6 using namespace std; 7 8 typedef long long ll; 9 const int N = 1001, M = 1024, W = 1e9; 10 int n, cur, nxt, va, vx, p[N]; 11 12 struct huge_int { 13 int len, a[40]; 14 huge_int(): len(1) { memset(a, 0, sizeof(a)); } 15 16 inline void operator += (const huge_int &b) { 17 b.len > len ? len = b.len : 0; 18 for (int i = 1; i <= len; ++i) { 19 a[i] += b.a[i]; 20 if (a[i] >= W) ++a[i + 1], a[i] -= W; 21 } 22 if (a[len + 1]) ++len; 23 return ; 24 } 25 26 inline void print() { 27 printf("%d", a[len]); 28 for (int i = len - 1; i; --i) 29 printf("%09d", a[i]); 30 puts(""); return ; 31 } 32 } f[2][M][3]; 33 34 char ch; 35 int read() { 36 while (ch = getchar(), ch < '0' || ch > '9'); 37 int res = ch - 48; 38 while (ch = getchar(), ch >= '0' && ch <= '9') res = res * 10 + ch - 48; 39 return res; 40 } 41 42 int main() { 43 freopen("sequence.in", "r", stdin); 44 freopen("sequence.out", "w", stdout); 45 n = read(); 46 for (int i = n; i; --i) p[i] = read(); 47 f[0][1023][0].a[1] = 1; 48 for (int i = 0; i < n; ++i) { 49 nxt = cur ^ 1; 50 for (int j = 0; j < M; ++j) 51 for (int k = 0; k <= 2; ++k) 52 f[nxt][j][k] = f[cur][j][k]; 53 for (int j = 0; j < M; ++j) { 54 va = p[i + 1] & j, vx = p[i + 1] ^ j; 55 f[nxt][va][1] += f[cur][j][0]; f[nxt][va][1] += f[cur][j][1]; 56 f[nxt][vx][2] += f[cur][j][1]; f[nxt][vx][2] += f[cur][j][2]; 57 } 58 cur ^= 1; 59 } 60 f[cur][0][2].print(); 61 fclose(stdin); fclose(stdout); 62 return 0; 63 } View Code

3. 長(zhǎng)途旅行
【 題目描述】
JY 是一個(gè)愛旅游的探險(xiǎn)家,也是一名強(qiáng)迫癥患者。現(xiàn)在 JY 想要在 C 國(guó)進(jìn)行一次長(zhǎng)途
旅行,C 國(guó)擁有 n 個(gè)城市(編號(hào)為 0,1,2...,n - 1),城市之間有 m 條道路,可能某個(gè)城市到自己
有一條道路,也有可能兩個(gè)城市之間有多條道路,通過每條道路都要花費(fèi)一些時(shí)間。JY 從
0 號(hào)城市開始出發(fā),目的地為 n – 1 號(hào)城市。由于 JY 想要好好參觀一下 C 國(guó),所以 JY 想要
旅行恰好 T 小時(shí)。為了讓自己的旅行更有意思,JY 決定不在任何一個(gè)時(shí)刻停留(走一條到城
市自己的路并不算停留)。JY 想知道是否能夠花恰好 T 小時(shí)到達(dá) n – 1 號(hào)城市(每個(gè)城市可
經(jīng)過多次) 。現(xiàn)在這個(gè)問題交給了你。
若可以恰好到達(dá)輸出“Possible”否則輸出“Impossible” 。(不含引號(hào))。
【 輸入格式】
第一行一個(gè)正整數(shù) Case,表示數(shù)據(jù)組數(shù)。
每組數(shù)據(jù)第一行 3 個(gè)整數(shù),分別為 n, m, T。
接下來 m 行,每行 3 個(gè)整數(shù) x, y, z,代表城市 x 和城市 y 之間有一條耗時(shí)為 z 的雙向邊。
【 輸出格式】
對(duì)于每組數(shù)據(jù)輸出”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
第二組:顯然偶數(shù)時(shí)間都是不可能的。
【 數(shù)據(jù)范圍】
30%: T <= 10000
另有 30%: n <= 5 , m <= 10.
100%: 2 <= n <= 50 , 1 <= m <= 100 , 1 <= z <= 10000 , 1 <= T <= 10^18 , Case <= 5.

T3:
30%:
當(dāng) T<= 10000 的時(shí)候,可以設(shè) vis[i][j] 代表到達(dá)第 i 個(gè)點(diǎn)時(shí)間為 j 是否合法。 這樣是
O(T*m),可以拿到小數(shù)據(jù)。
另外的那 30%:各種奇怪的騙分方法。選手自行考慮。
100%:
當(dāng) T 很大的時(shí)候,我們考慮 如果 0 -> x -> n - 1 路徑時(shí)間為 T,且 從 x 出發(fā)有一個(gè)時(shí)
間為 d 的環(huán),則 一定存在一個(gè) K 滿足 K + p*d = T(至少 T 滿足條件) ,這樣我們就能繞著
環(huán)走 p 次就能構(gòu)成一條時(shí)間為 T 的路徑。
顯然要求的路徑一定經(jīng)過 0,而且在合法情況下從 0 號(hào)點(diǎn)出發(fā)一定存在一條邊,否則 0
號(hào)點(diǎn)和 n - 1 號(hào)就是不聯(lián)通的。 隨便取一條邊時(shí)間為 d, 則能構(gòu)成從 0 號(hào)點(diǎn)出發(fā)的一個(gè)時(shí)間為
2d 的環(huán)。這樣原題就化為最短路問題了,dis[i][j] 代表到達(dá) i 號(hào)點(diǎn),時(shí)間為 j + p * 2d,最小
的 j+p*2d,
最后判斷 dis[n -1][T % 2d] 是否小于等于 T 即可。
實(shí)際上就是在 30%的基礎(chǔ)上縮減狀態(tài)。
時(shí)間復(fù)雜度為 O(m*d)。

1 #include <algorithm> 2 #include <iostream> 3 #include <cstring> 4 #include <cstdio> 5 #include <cmath> 6 #include <queue> 7 using namespace std; 8 9 #define X first 10 #define Y second 11 #define mk make_pair 12 typedef pair<int, int> DI; 13 typedef long long ll; 14 const int N = 51, M = 201, K = 20001; 15 int n, m, len, u, v, c, Case; 16 int tot, info[N], nxt[M], go[M], val[M]; 17 ll T, INF, dist[N][K]; 18 queue<DI> que; 19 bool vis[N][K]; 20 21 inline void SetE(int x, int y, int z) { 22 nxt[++tot] = info[x]; info[x] = tot; go[tot] = y; val[tot] = z; 23 nxt[++tot] = info[y]; info[y] = tot; go[tot] = x; val[tot] = z; 24 return ; 25 } 26 27 inline void Spfa() { 28 int x, y, p, q; ll v; 29 memset(dist, 63, sizeof(dist)); 30 dist[0][0] = 0; que.push(mk(0, 0)); 31 while (!que.empty()) { 32 DI top = que.front(); que.pop(); 33 x = top.X, p = top.Y; vis[x][p] = false; 34 for (int k = info[x]; y = go[k], k; k = nxt[k]) { 35 v = dist[x][p] + val[k]; q = v % len; 36 if (dist[y][q] > v) { 37 dist[y][q] = v; 38 if (!vis[y][q]) { 39 vis[y][q] = true; 40 que.push(mk(y, q)); 41 } 42 } 43 } 44 } 45 return ; 46 } 47 48 char ch; 49 inline int read() { 50 while (ch = getchar(), ch < '0' || ch > '9'); 51 int res = ch - 48; 52 while (ch = getchar(), ch >= '0' && ch <= '9') res = res * 10 + ch - 48; 53 return res; 54 } 55 inline ll Read() { 56 while (ch = getchar(), ch < '0' || ch > '9'); 57 ll res = ch - 48; 58 while (ch = getchar(), ch >= '0' && ch <= '9') res = res * 10 + ch - 48; 59 return res; 60 } 61 62 int main() { 63 freopen("travel.in", "r", stdin); 64 freopen("travel.out", "w", stdout); 65 Case = read(); 66 while (Case--) { 67 n = read(), m = read(); T = Read(); 68 memset(info, 0, sizeof(info)); tot = 0; 69 for (int i = 1; i <= m; ++i) { 70 u = read(), v = read(); c = read(); 71 SetE(u, v, c); 72 } 73 if (!info[0]) puts("Impossible"); 74 else { 75 len = 10001; 76 for (int k = info[0]; k; k = nxt[k]) 77 if (val[k] < len) len = val[k]; 78 len *= 2; Spfa(); 79 if (dist[n - 1][T % len] <= T) puts("Possible"); 80 else puts("Impossible"); 81 } 82 } 83 fclose(stdin); fclose(stdout); 84 return 0; 85 } View Code

?

轉(zhuǎn)載于:https://www.cnblogs.com/J-william/p/6063373.html

總結(jié)

以上是生活随笔為你收集整理的全国信息学奥林匹克联赛 ( NOIP2014) 复赛 模拟题 Day1 长乐一中的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。