開學第三測
(題目分析摘自dalao博客
https://blog.csdn.net/todobe/article/details/54617259
https://blog.csdn.net/cdqzgxxqdql/article/details/53085481)
P71
競賽時間:???? 年?? 月?? 日??:??-??:??
題目名稱 | 智乃 | 麻耶 | 惠 |
名稱 | kahuucino | zyougamaya | nacumegu |
輸入 | kahuucino.in | zyougamaya.in | nacumegu.in |
輸出 | kahuucino.out | zyougamaya.out | nacumegu.out |
每個測試點時限 | 1秒 | 1秒 | 1秒 |
內存限制 | 512MB | 512MB | 512MB |
測試點數目 | 20 | 10 | 10 |
每個測試點分值 | 5 | 10 | 10 |
是否有部分分 | 無 | 無 | 無 |
題目類型 | 傳統 | 傳統 | 傳統 |
T1
智乃
【題目描述】
給你N個字符串,你每次可以選擇其中一個字符串的一段前綴進行翻轉,但是你必須保證這個前綴的長度是偶數。你可以進行無限次這樣的操作,並且如果
兩個字符串變得相同的時候,你就可以把這兩個字符串都刪除掉,問最后最少剩下多少個字符串?
【輸入格式】
第一行一個整數T代表數據組數。
對於每組數據,第一行一個整數N代表字符串個數。
接下來N行每行一個字符串。
【輸出格式】
對於每組數據,一行一個整數代表答案。
【樣例輸入】
2
5
esprit
god
redotopc
odcpoter
dog
14
rats
live
stressed
to
act
as
star
desserts
of
evil
cat
sa
fo
ot
【樣例輸出】
3
0
【樣例解釋】
無。
【數據范圍與規定】
40%的數據,字符串長度不超過8。
對於100%的數據,1 ≤ T≤ 11,字符串長度不超過50,1 ≤ N ≤ 50。
思路:很容易證明:將這個字符串分成兩個字符+兩個字符+……,兩個字符為一組,將一組作為基礎,每組可以出現在任何位置,且每組的兩個字符可以互換。那么直接排序每組,每組內再排序,就行。要注意:字符串的長度為奇數時,最后一組的第二個設為0。

#include <algorithm> #include <iostream> #include <vector> #include <cstdio> #include <string> #include <set> using namespace std; set<string> h; string a[55]; int getMin(vector<string> words) { int n = words.size(), ans = n; h.clear(); //清空操作 for (int i = 0; i < n; i++) { int m = words[i].size(); string s = ""; for (int j = 0; j*2 < m; j++) { char x = words[i][j*2], y = words[i][j*2+1]; if (x > y) swap(x, y); a[j] = x, a[j] += y; } sort(a, a+m/2); for (int j = 0; j*2 < m; j++) s += a[j]; if (m & 1) s += words[i][m-1]; //位運算符 & //http://www.runoob.com/cplusplus/cpp-operators.html if (h.find(s) == h.end()) h.insert(s); else h.erase(s), ans -= 2; } return ans; } int main() { // freopen("kahuucino.in","r",stdin); // freopen("kahuucino.out","w",stdout); int T, n, m; char ch; string s; vector<string> w; scanf("%d", &T); while (T--) { scanf("%d%d", &n, &m); w.clear(); //初始化,將vector數組清空 for(int i = 0; i < n; i++) cin >> s, w.push_back(s); //尾部插入剛輸入的字符串 s printf("%d\n", getMin(w)); //調用函數 } return 0; }

#include<queue> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; struct node { int fi, se; } gg[55][55]; int judge[55], num[55], ans; int cmp(const node &a, const node &b) { if(a.fi != b.fi) return a.fi < b.fi; return a.se < b.se; } void search(int k) { int bbbb = 0; for(int i = 1; i < k; i++) if(!judge[i] && num[i] == num[k]) { int q = num[i]>>1; if((num[i] & 1) == 1) q++; for(int j = 1; j <= q; j++) { if(gg[i][j].fi != gg[k][j].fi || gg[i][j].se != gg[k][j].se) break; if(j == q) bbbb = 1; } if(bbbb) { ans -= 2; judge[i] = judge[k] = 1; return ; } } } int main() { // freopen("kahuucino.in","r",stdin); // freopen("kahuucino.out","w",stdout); int T; scanf("%d", &T); while(T--) { memset(judge, 0, sizeof(judge)); memset(gg, 0, sizeof(gg)); int n; scanf("%d", &n); ans = n; for(int i = 1; i <= n; i++) { int tot = 0; char s[55]; scanf("%s", s+1); num[i] = strlen(s+1); if((num[i] & 1) == 0) for(int j = 1; j <= num[i]; j += 2) { int x1 = s[j]-'a'+1, x2 = s[j+1]-'a'+1; gg[i][++tot].fi = min(x1,x2); gg[i][tot].se = max(x1,x2); } else { for(int j = 1; j <= num[i]-1; j += 2) { int x1 = s[j]-'a'+1, x2 = s[j+1]-'a'+1; gg[i][++tot].fi = min(x1,x2); gg[i][tot].se = max(x1,x2); } gg[i][++tot].fi = s[num[i]]-'a'+1; } sort(gg[i]+1, gg[i]+1+tot, cmp); search(i); } printf("%d\n", ans); } return 0; }
T2
麻耶
【問題描述】
油庫里是幻想鄉特有的一種生物。每只油庫里都有一個戰斗力值和一個能量值。當兩只油庫里戰斗時,總是戰斗力值高的一位獲勝。獲勝者的戰斗力值將變
成(自己的原戰斗力值-對手的戰斗力值+對手的能量值)。敗者將死去。若兩者戰斗力值一樣,則同歸於盡。(這句漏下了qwq)
思考熊發現了很多油庫里,他想知道通過互相戰斗之后油庫里中戰斗力值+能量值最高的一個可能到達多少。你能幫他們求出來嗎?(假設除了考察的那只
油庫里之外,其他油庫里之間不會發生戰斗)
【輸入格式】
第一行是一個整數N,代表當前有多少油庫里。
接下來的N行, 每一行有兩個整數u,v, 代表這只油庫里的戰斗力值和能量值。
【輸出格式】
輸出一個整數,代表油庫里中戰斗力值+能量值最高的一個能達到多少。
【樣例輸入】
2
1 2
2 1
【樣例輸出】
4
【樣例解釋】
無。
【數據規模與約定】
數據點編號 | N = | 數據點編號 | N = |
1 | 2 | 6 | 14989 |
2 | 984 | 7 | 21726 |
3 | 6168 | 8 | 100000 |
4 | 10470 | 9 | 100000 |
5 | 19168 | 10 | 100000 |
思路:簡單貪心。將每只油庫里按戰斗力從大到小排序,枚舉。每枚舉到一只油庫里進行三個判斷:
1、打這只油庫里。
2、不打這只油庫里。
3、從這只油庫里重新開始。
這里解釋一下第三個判斷。如果之前的油庫里打到當前這只油庫里,並且如果打這只或不打這只的戰斗力+能量還沒有直接選當前這只油庫里的戰斗力+能量大的話,選當前這只。

#include<algorithm> #include<cstdio> #define N 100005 using namespace std; int n; int x[N], y[N]; int sum[N]; int ans[N]; int main() { freopen("zyougamaya.in","r",stdin); freopen("zyougamaya.out","w",stdout); int maxn = -1; scanf("%d", &n); for(int i = 1; i <= n; i++) { scanf("%d%d", &x[i], &y[i]); sum[i] = y[i]-x[i]; ans[i] = x[i]+y[i]; } for(int i = 1; i <= n; i++) { for(int j = 1; j <= n; j++) { if(i == j) continue; ans[i] = max(ans[i], ans[i]+sum[j]); } maxn = max(maxn, ans[i]); } printf("%d", maxn); fclose(stdin); fclose(stdout); return 0; }
(dalao們就不要看我的了 捂臉)

#include<cstdio> #include<cstdlib> #include<cstring> #include<algorithm> using namespace std; #ifdef unix #define LL "%lld" #else #define LL "%I64d" #endif const int maxn = 100010; int n; struct Yukkuri { int f, e; void init() { scanf("%d%d", &f, &e); } bool operator<(const Yukkuri &a)const { if (f == a.f) return e>a.e; else return f<a.f; } } yukkuri[maxn]; int main() { // freopen("zyougamaya.in","r",stdin); // freopen("zyougamaya.out","w",stdout); scanf("%d",&n); int cnt=0; long long ans=0; for (int a=1; a<=n; a++) { yukkuri[++cnt].init(); ans=max(ans,(long long)yukkuri[cnt].f+yukkuri[cnt].e); } sort(yukkuri+1,yukkuri+cnt+1); long long sum=0; for (int a=1; a<=cnt;) if (a==1) { int b=a; while (b<=cnt && yukkuri[b].f==yukkuri[a].f) sum+=yukkuri[b].e-yukkuri[b].f,b++; a=b; } else { ans=max(ans,sum+yukkuri[a].f+yukkuri[a].e); if (yukkuri[a].f<yukkuri[a].e) sum+=yukkuri[a].e-yukkuri[a].f; a++; } printf(LL "\n",ans); return 0; }

#include<queue> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; struct node{ long long fight,power,give,sum; }gg[100005]; inline int read() { int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } int cmp(const node&a,const node&b) { if(a.fight>b.fight)return true; else if(a.fight<b.fight)return false; if(a.fight==b.fight&&a.power>b.power)return true; else return false; } int main() { freopen("zyougamaya.in","r",stdin); freopen("zyougamaya.out","w",stdout); int n=read(); for(int i=1;i<=n;i++) { scanf("%I64d%I64d",&gg[i].fight,&gg[i].power); gg[i].give=gg[i].power-gg[i].fight; gg[i].sum=gg[i].power+gg[i].fight; } sort(gg+1,gg+n+1,cmp); for(int i=2;i<=n;i++) if(gg[i].fight!=gg[i-1].fight&&gg[i-1].fight+gg[i].give+gg[i-1].power>gg[i-1].sum&&gg[i-1].fight+gg[i].give+gg[i-1].power>gg[i].sum) { gg[i].fight=gg[i-1].fight+gg[i].give; gg[i].power=gg[i-1].power; gg[i].give=gg[i].power-gg[i].fight; gg[i].sum=gg[i].power+gg[i].fight; } else if(gg[i-1].sum>gg[i].sum||(gg[i-1].sum==gg[i].sum&&gg[i-1].power>gg[i].power)) { gg[i].fight=gg[i-1].fight; gg[i].power=gg[i-1].power; gg[i].give=gg[i].power-gg[i].fight; gg[i].sum=gg[i].power+gg[i].fight; } printf("%I64d",gg[n].sum); return 0; }
T1
惠
【問題描述】
現在你要實現一個文件系統,支持以下操作
cd Directory_Name
如果當前路徑下有名為 Directory_Name 的文件夾,則進入該文件夾所對應的路徑,否則輸出“No such directory!” 。
cd ..
如果當前路徑存在父路徑, 則返回父路徑, 否則輸出 “No parent directory!” 。
touch File_Name
如果當前目錄下存在名為 File_Name 的文件則輸出“File already exists!” ,否則創建這樣一個文件。
rm File_Name
如果當前目錄下存在名為 File_Name 的文件則刪除它,否則輸出“No suchfile!” 。
mkdir Directory_Nam e
如果在當前路徑下存在名為 Directory_Name 的文件夾,則輸出“Directoryalready exists!” ,否則創建這樣一個文件夾(當前路徑不變) 。
rmdir Directory_Name
如果在當前路徑下存在名為 Directory_Name 的文件夾,則刪除之,否則輸出“No such directory!” 。
ls
列出當前路徑下所有的文件和文件夾,每一項占一行,按創建的先后順序給出。采用以下形式輸:
“Item_Name Type” (Type 為 <D>(文件夾)或<F>(文件))
注意:同一路徑下文件與文件夾可以同名,但同一路徑下文件與文件、文件夾與文件夾不能同名。
初始時當前路徑處於根路徑下,無父路徑。
【輸入格式】
第一行為Q,表示有Q個操作。
接下來是Q行,每行輸入為以上描述的操作之一。
【輸出格式】
輸出答案。
【樣例輸入】
3
mkdir standy
touch totalfrank
ls
【樣例輸出】
standy <D>
totalfrank <F>
【樣例解釋】
無。
【數據規模與約定】
對於100%的數據,1 ≤ Q ≤ 100,所有文件名字長度不超過200且均為小寫字母。
思路:炒雞大模擬啊。。。
(因為標程太長(200多行呢qwq)所以我選擇只把dalao的程序拿上來 不要說我懶 我只是特別懶而已 哈哈)
我是不會告訴你們我沒有看懂題目滴。。。

#include<map> #include<queue> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; int tot=1,fa[3005],now=1,judge[3005]; string que[3005]; void touch() { string s2; cin>>s2; for(int i = 1; i <= tot; i++) if(que[i]==s2 && fa[i]==now && judge[i]==1) { printf("File already exists!\n"); return ; } fa[++tot] = now; que[tot] = s2; judge[tot] = 1; } void mkdir() { string s2; cin>>s2; for(int i = 1; i <= tot; i++) if(que[i] == s2 && fa[i]==now && judge[i]==2) { printf("Directory already exists!\n"); return ; } fa[++tot] = now; que[tot] = s2; judge[tot] = 2; } void rmdir() { string s2; cin>>s2; for(int i = 1; i <= tot; i++) if(que[i]==s2 && fa[i]==now && judge[i]==2) { fa[i] = -1; return ; } printf("No such directory!\n"); } void rm() { string s2; cin>>s2; for(int i = 1; i <= tot; i++) if(que[i]==s2 && fa[i]==now && judge[i]==1) fa[i]=-1;return ; printf("No such file!\n"); } void sd() { string s2; cin>>s2; if(s2[0] == '.') { if(fa[now]) { now = fa[now]; return ; } else { printf("No parent directory!\n");return ; } } for(int i = 1; i <= tot; i++) if(que[i]==s2 && fa[i]==now && judge[i]==2) { now = i; return ; } printf("No such directory!\n"); } void ls() { for(int i = 1; i <= tot; i++) if(fa[i]==now) { cout<<que[i]; if(judge[i] == 1) printf(" <F>\n"); else printf(" <D>\n"); } } int main() { // freopen("nacumegu.in","r",stdin); // freopen("nacumegu.out","w",stdout); int q; scanf("%d", &q); judge[now] = 2; while(q--) { string s1; cin>>s1; int len = s1.size(); if(len == 5) { if(s1[len-1] == 'h') touch(); else if(s1[0]=='m') mkdir(); else rmdir(); } else { if(s1[len-1]=='s') ls(); else if(s1[len-1]=='m') rm(); else sd(); } } return 0; }
PS:某些人不要在下邊亂評論了。。。