国庆七天乐 Day5
今天做的是第五屆河南省省賽,我挫到爆了,只出了三題,都是水題,個人賽墊底。
先總結一下,今天寫最水的A題居然WA了兩次,關鍵是調了半個小時,浪費了不少時間,也影響了心情。然后做的是同樣水的
F題,還好敲的比較快,也順利一A。然后剩下三個多小時在夢游,將D題敲到了200多行,WA了2次,中途去寫了G題,結果題意看錯了,
WA了1次,看各位大牛已經A到了7題,又回來寫D題,還是WA,最后才想到B題過的人也那么多,所以去寫B題,WA了兩次才A。慘不忍睹!
A:奇怪的排序
將一個數組的所有數翻轉,然后從小到大排序,輸出排序后的結果,例如13翻轉成31,超級水的一道題,真心不應該
#include <stdio.h> #include <string.h> #include <stdlib.h>const int MAXD = 60; typedef struct Node {int x, y; }E; E e[MAXD]; int A, B;int cmp(const void *_p, const void *_q) {E *p = (E *)_p;E *q = (E *)_q;return p -> y - q -> y; }int main() {int n;scanf("%d", &n);while(n --){scanf("%d%d", &A, &B);int k = 0;for(int i = A; i <= B; i ++){e[k].x = i;char str[20];int t = i, m = 0;while(t){str[m ++] = t % 10 + '0';t /= 10;}str[m] = '\0';//printf("%s\n", str);int s = 1, j;e[k].y = 0;for(j = strlen(str) - 1; j >= 10; )if(str[j] == '0') j --;for(; j >= 0 ; j --){e[k].y += (str[j] - '0') * s;s *= 10;}//printf("%d\n", e[k].y);k ++;}qsort(e, k, sizeof e[0], cmp);k --;for(int i = 0; i < k; i ++){printf("%d ", e[i].x);}printf("%d\n", e[k].x);}return 0; }B: 最強DE 戰斗力
將一個1000以內的數拆成N個數,N不給出,自己判斷,使得這N個數的乘積最大,需要用到高精度,但是這不是關鍵。最后才想到拆成3 和 2是最優的,優先選3。
#include <stdio.h> #include <string.h> #include <stdlib.h> #include <iostream> using namespace std;const int base = 10000; const int width = 4; const int N = 1000; struct bint {int ln, v[N];bint (int r = 0){for(ln = 0; r > 0; r /= base) v[ln ++] = r % base;}bint & operator = (const bint& r){memcpy(this, &r, (r.ln + 1) * sizeof (int));return *this;} };/* bool operator <(const bint& a, const bint& b) {int i;if(a.ln != b.ln) return a.ln < b.ln;for(i = a.ln - 1; i >= 0 && a.v[i] == b.v[i]; i --){return i < 0 ? 0 : a.v[i] < b.v[i];} } */bint operator * (const bint& a, const bint& b) {bint res;res.ln = 0;if(0 == b.ln) {res.v[0] = 0; return res;}int i, j, cy;for(i = 0; i < a.ln; i ++){for(j = cy = 0; j < b.ln || cy > 0; j ++, cy /= base){if(j < b.ln) cy += a.v[i] * b.v[j];if(i + j < res.ln) cy += res.v[i + j];if(i + j >= res.ln) res.v[res.ln ++] = cy % base;else res.v[i + j] = cy % base;}} }bool read(bint& b, char buf[]) {//if(1 != scanf("%s", buf)) return 0;int w, u, ln = strlen(buf);memset(&b, 0, sizeof(bint));if('0' == buf[0] && 0 == buf[1]) return 1;for(w = 1, u = 0; ln; ){u += (buf[-- ln] - '0') * w;if(w * 10 == base){b.v[b.ln ++] = u, u = 0, w = 1;}else w *= 10;}if(w != 1) b.v[b.ln ++] = u;return 1; }void write(const bint& v) {int i;printf("%d", v.ln == 0 ? 0 : v.v[v.ln - 1]);for(i = v.ln - 2; i >= 0; i --)printf("%04d", v.v[i]);printf("\n"); }int n, t; bint s, v, u;int main() {scanf("%d", &n);while(n --){scanf("%d", &t);int k = t / 3;char str1[10] = "1", str2[10] = "2", str3[10] = "3";read(s, str1);read(v, str2);read(u, str3);//write(s);//write(v);//write(u);for(int i = 0; i < k - 1; i ++){s = s * u;}if(t % 3 == 1){s = s * v;s = s * v;}else if(t % 3 == 2){s = s * u;s = s * v;}else{s = s * u;}write(s);}return 0; }C: 試 制 品
一道關于字符串的題,暫時沒看。
D:遙控器
這道題是一道類似模擬調頻道的題。
Dr.Kong 有一臺高級電視機,這臺電視機可以接受100個頻道(從0到99編號)。電視的配套
遙控器有13個按鈕:
1??? 2?? 3?? ↑
4??? 5??? 6?? ↓
7??? 8?? 9
—?? 0
當按"↑"鍵時,當前頻道編號會增加1(如果當前為99頻道,則會切換到0頻道)。如果按"↓"
鍵,當前頻道編號會減小1(如果當前為0頻道,則會切換到99頻道)。當要切換到0~9頻道時,可以
直接在遙控器上按相應的鍵。當要切換到10~99頻道時,可以先按"—"鍵,然后按2個與頻道編號
相對應的數字鍵(即先按與頻道編號的十位數字相對應的鍵,然后按與個位數字相對應的鍵)。
由于遙控器長時間的使用和某些未知原因,遙控器上的某些鍵已經壞了,不能再起作用了。
現在你的任務是,能否告訴Dr.Kong,如何用最少的按鍵次數來將頻道從編號X切換到編號Y。
我當時是根據鍵來枚舉,越來越亂,越寫越多,最后就悲劇了。
其實應該按照步數來枚舉,枚舉需要按上下鍵的步數。如果我們只通過按上下的話,從X到Y的步數可以直接求。
從任一個可通過按數字鍵到的頻道到Y的步數 + 數字鍵到該頻道的步數也可以求。然后找出最小值即可。
#include <stdio.h> #include <string.h> #include <stdlib.h> int a[15]; int x, y; int cnt, ans; int id(int x) {if(x < 0)return x + 100;elsereturn x % 100; }int min(int a, int b) {if(a == -1)return b;elsereturn a < b ? a : b; }int to(int x) {x = id(x);if(x / 10 == 0){return a[x];}int tx = x / 10, bx = x % 10;if(a[10] && a[tx] && a[bx])return 3;return 0; }int main() {//freopen("543.in", "r", stdin);//freopen("D.out", "w", stdout);int t;scanf("%d", &t);while(t --){ans = -1;scanf("%d%d%d%d", &a[1], &a[2], &a[3], &a[11]);scanf("%d%d%d%d", &a[4], &a[5], &a[6], &a[12]);scanf("%d%d%d", &a[7], &a[8], &a[9]);scanf("%d%d", &a[10], &a[0]);scanf("%d%d", &x, &y);//枚舉步數for(int i = 0; i < 100; i ++){if(a[11]){if(id(y - i) == x) //向上按i次ans = min(ans, i);else if(to(y - i)) //可以到一個頻道 + 向上i次ans = min(ans, to(y - i) + i);}if(a[12]){if(id(y + i) == x)//向下按i次 {ans = min(ans, i);}else if(to(y + i))//到一個頻道 + 向下i次ans = min(ans, to(y + i) + i);}}printf("%d\n", ans);}return 0; }比賽時寫的挫B代碼:
View Code #include <stdio.h> #include <string.h> #include <stdlib.h> #include <algorithm> using namespace std; int a[15]; int x, y; int cnt, ans;int main() {int t;scanf("%d", &t);while(t --){ans = 110;scanf("%d%d%d%d", &a[1], &a[2], &a[3], &a[11]);scanf("%d%d%d%d", &a[4], &a[5], &a[6], &a[12]);scanf("%d%d%d", &a[7], &a[8], &a[9]);scanf("%d%d", &a[10], &a[0]);scanf("%d%d", &x, &y);int cur, ty, by;bool ok = false;if(a[11]){ok = true;if(y < x){cnt = y + 99 - x;ans = min(cnt, ans);}else{cnt = y - x;ans = min(cnt, ans);}}if(a[12]){ok = true;if(y < x){cnt = x - y;ans = min(cnt, ans);}else{cnt = x + 99 - y;ans = min(cnt, ans);}}if(y < 10){if(a[y]){cnt = 1;if(cnt < ans) ans = cnt;ok = true;}else{cur = y;if(a[11]){while(cur --){if(a[cur]){cnt = y - cur;if(cnt < ans) ans = cur;ok = true;break;}if(cur == -1) cur = 99;if(cur >= 10){if(!a[10]) break;ty = cur / 10, by = cur % 10;if(a[ty] && a[by]){ok = true;cnt = 3;cnt += (y + 99 - cur);if(cnt < ans) ans = cnt;}}}}cur = y;if(a[12]){while(cur ++){if(a[cur]){cnt = cur - y;if(cnt < ans) ans = cur;ok = true;break;}if(cur == 100) cur = 0;if(cur >= 10){if(!a[10]) break;ty = cur / 10, by = cur % 10;if(a[ty] && a[by]){ok = true;cnt = 3;cnt += (cur - y);if(cnt < ans) ans = cnt;}}}}}}else{ty = y / 10, by = y % 10;if(a[ty] && a[by]){cnt = 3;ans = min(cnt, ans);ok = true;}else{cur = y;if(a[11]){while(cur --){if(cur > 0)}}}}}}E:奇妙的圖案
計算幾何,暫時先不搞。
F:Metric??? Matrice
判斷一個矩陣是不是最短路徑的矩陣。是的話輸出”0“,否則看違反了下哪條規則就輸出幾,遍歷五遍矩陣就可以了。
?
A distance matrix a[i][j] is a metric if and only if
??? 1.??? a[i][i] = 0
2,??? a[i][j]> 0??? if i != j
??? 3.??? a[i][j] = a[j][i]
4.??? a[i][j] + a[j][k] >= a[i][k]?? i != j != k
G: Divideing?? Jewels
給出權值從1到10的物品的各自的數目,然后問是否能平均分給兩個人,使得兩個人拿到的物品的總價值相等。首先判斷所有物品的總價值是不是偶數,是偶數
的話再看能不能將這些物品分配到一個人手里,使得他獲得的價值是總價值的一半。可以轉化成多重背包問題,知道了物品的價值和數目,我們可以將物品的體積
設成和它的價值相同,然后用一個總價值一半體積的背包來裝這些物品,看最終獲得的最大價值是不是等于它的體積。
#include <stdio.h> #include <string.h> #include <stdlib.h> #include <algorithm> using namespace std; const int MAXN = 100005; int a[15], f[MAXN], V;void ZeroOnePack(int F[], int C, int W) {for(int v = V; v >= C; v --)F[v] = max(F[v], F[v - C] + W); }void CompletePack(int F[], int C, int W) {for(int v = C; v <= V; v ++)F[v] = max(F[v], F[v - C] + W); }void MultiplePack(int F[], int C, int W, int M) {if(C * M >= V){CompletePack(F, C, W);return;}int k = 1;while(k < M){ZeroOnePack(F, k * C, k * W);M -= k;k <<= 1;}ZeroOnePack(F, C * M, W * M); }int main() {int t = 0;while(true){int total = 0;for(int i = 1; i <= 10; i ++){scanf("%d", &a[i]);total += a[i] * i;}if(total == 0) break;++ t;if(total & 1)printf("#%d:Can't be divided.\n", t);else{int target = total >> 1;memset(f, 0, sizeof f);V = target;for(int i = 1; i <= 10; i ++){MultiplePack(f, i, i, a[i]);}if(f[target] == target){printf("#%d:Can be divided.\n", t);}elseprintf("#%d:Can't be divided.\n", t);printf("\n");}}return 0; }?
H: Interesting Punch-Bowl
神題,貌似當時他們省賽沒人過,但是被斌牛搞定了。
?
?
轉載于:https://www.cnblogs.com/Yu2012/archive/2012/10/05/2712353.html
總結
以上是生活随笔為你收集整理的国庆七天乐 Day5的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: POJ1083 Moving Table
- 下一篇: thinkphp3.0部分总结