A. Left-handers, Right-handers and Ambidexters
题意:有l个人擅长用左手,有r个人擅长用右手,有a个人可以选择用左手或右手。现在需要构建一个含偶数人的队伍,其中用左手和右手的人数相等,求队伍人数?
思路:简单题
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 using namespace std; 5 int main() 6 { 7 int l, r, a; 8 scanf("%d%d%d", &l, &r, &a); 9 int Min = min(l, r) + a,Max=max(l,r); 10 int ans; 11 if (Min <= Max) ans = 2 * Min; 12 else ans = 2 * Max + 2*((Min - Max) / 2); 13 printf("%d\n", ans); 14 return 0; 15 }
B. Intercepted Message
题意:有两条信息,包含相同的文件(大小一样、排列顺序一样),每个文件分成若干包按照顺序在网上传送。已知每个包的大小,求文件可能的最大数目?
思路:从头到尾遍历,当和相同时数目+1
1 #include<iostream> 2 #include<cstdio> 3 using namespace std; 4 const int maxn = 100010; 5 int a[maxn], b[maxn]; 6 int main() 7 { 8 int n, m; 9 scanf("%d%d", &n, &m); 10 for (int i = 0; i < n; i++) scanf("%d", a + i); 11 for (int i = 0; i < m; i++) scanf("%d", b + i); 12 int ans = 0,tmpa=0,tmpb=0,i=0,j=0; 13 while (i <n||j <m) 14 { 15 if (tmpa==tmpb&&tmpa==0) tmpa += a[i++],tmpb+=b[j++] ; 16 else 17 { 18 if (tmpa < tmpb) tmpa += a[i++]; 19 else if (tmpb < tmpa) tmpb += b[j++]; 20 } 21 if (tmpa == tmpb)ans++, tmpa = tmpb = 0; 22 } 23 printf("%d\n", ans); 24 return 0; 25 }
C. Zebras
题意:有一个01串,现在问能否分成k个子串(子串中0和1不一定在原串中连续),每个子串以0作为开始和结尾,0和1在串中交替。给出任意一种可行方案。
思路:用vector模拟子串。当当前字符为‘0’时,如果有串为1结尾,0必须放在其后面,否则可以自成新串的开头;如果当前为1,则只能放在0结尾的子串后面
1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 #include<vector> 5 using namespace std; 6 const int maxn = 200010; 7 char str[maxn]; 8 int num0=0, num1=0; 9 vector<int>List[maxn]; 10 int main() 11 { 12 scanf("%s", str + 1); 13 int len = strlen(str + 1); 14 for (int i = 1; i <= len; i++) if (str[i] == ‘0‘) num0++; 15 num1 = len - num0; 16 if (num1 >= num0 || str[1] == ‘1‘||str[len]==‘1‘) printf("-1\n"); 17 else 18 { 19 int curnum = 0,onenum=0;//前者表示List[0]~List[curnum-1]都是以0作为结尾的子串,后者表示List[curnum]~List[curnum+onenum-1]为1作为结尾的子串 20 for (int i = 1; i <= len; i++) 21 { 22 if (str[i] == ‘0‘) 23 { 24 List[curnum++].push_back(i); 25 if (onenum) onenum--; 26 } 27 else List[--curnum].push_back(i), onenum++; 28 if (curnum < 0) break; 29 } 30 if (onenum != 0) printf("-1\n"); 31 else 32 { 33 printf("%d\n", curnum); 34 for (int i = 0; i < curnum; i++) 35 { 36 int sz = List[i].size(); 37 printf("%d", sz); 38 for (int j=0; j < sz; j++) printf(" %d", List[i][j]); 39 printf("\n"); 40 } 41 } 42 } 43 return 0; 44 }
D. A Leapfrog in the Array
题意:有n个数,第i个数放在(i+1)/2的位置。每次选取位置最大的数,将其挪至其左侧与其最近的空位置,直至所有数字都在前n个位置。现在有q个询问,问所有操作过后,第qi个位置是哪个数字?
思路:手动模拟一边可知,所有奇数位置不变,所有偶数位置按照+bias,bias/2(init:bias=n-index/2)知道加至bias为奇数为止。
1 #include<iostream> 2 #include<cstdio> 3 using namespace std; 4 typedef long long LL; 5 int main() 6 { 7 LL n; 8 int q; 9 scanf("%I64d%d", &n, &q); 10 for (int i = 1; i <= q; i++) 11 { 12 LL index; 13 scanf("%I64d", &index); 14 if (index % 2 == 1) printf("%I64d\n", (index + 1) / 2); 15 else 16 { 17 LL init = n - index / 2; 18 while (init % 2 == 0) index += init, init /= 2; 19 index = (index + init + 1) / 2; 20 printf("%I64d\n", index); 21 } 22 } 23 return 0; 24 }