飞步无人驾驶2018届校园招聘在线笔试A轮
A.ABC
杂货铺老板一共有N件物品,每件物品具有ABC三种属性中的一种或多种。从杂货铺老板处购得一件物品需要支付相应的代价。
现在你需要计算出如何购买物品,可以使得ABC三种属性都在购买的物品中出现,并且支付的总代价最小。
Input第一行包含一个整数N。
以下N行,每行包含一个整数C和一个只包含"ABC"的字符串,代表购得该物品的代价和其具有的属性。
对于50%的数据,1 ≤ N ≤ 20
对于100%的数据,1 ≤ N ≤ 1000 1 ≤ C ≤ 100000
Output一个整数,代表最小的代价。如果无论如何凑不齐ABC三种属性,输出-1。
Sample Input
5 10 A 9 BC 11 CA 4 A 5 B
Sample Output
13
1 #include <bits/stdc++.h> 2 using namespace std; 3 int n; 4 int a[10]; 5 int vis[3]; 6 int c; 7 string s; 8 int main(){ 9 scanf("%d",&n); 10 memset(a,0x3f3f3f3f,sizeof(a)); 11 a[0] = 0; 12 for (int i = 0;i < n;++i){ 13 scanf("%d",&c); 14 cin >> s; 15 memset(vis,0,sizeof(vis)); 16 int cnt = 0; 17 for (int j = 0;j < s.length();j++){ 18 if (s[j] == 'A' && !vis[0]){ 19 cnt++; 20 vis[0] = 1; 21 } 22 if (s[j] == 'B' && !vis[1]){ 23 cnt += 2; 24 vis[1] = 1; 25 } 26 if (s[j] == 'C' && !vis[2]){ 27 cnt += 4; 28 vis[2] = 1; 29 } 30 } 31 a[cnt] = min(a[cnt],c); 32 } 33 int ans = 1e9+7; 34 for (int i = 0;i < 6;++i){ 35 for (int j = 0;j < 7;++j){ 36 for (int k = j+1;k < 8;++k){ 37 if (a[i] == 0x3f3f3f3f || a[j] == 0x3f3f3f3f || a[k] == 0x3f3f3f3f) continue; 38 if (((i&1) || (j&1) || (k&1)) && ((i&2) || (j&2) || (k&2)) && ((i&4) || (j&4) || (k&4))){ 39 ans = min(ans,a[i] + a[j] + a[k]); 40 } 41 } 42 } 43 } 44 if (ans == 1e9+7){ 45 puts("-1"); 46 }else printf("%d\n",ans); 47 }
B.等分字符串
给定一个只包含0-9的字符串S,请你判断能否将S划分为两个或两个以上连续的子串,使得每一个子串中的数字总和都相等。
Input输入包含多组数据。
第一行包含一个整数N,代表数据组数。
以下N行,每行包含一个字符串S。
对于50%的数据,2 ≤ |S| ≤ 100
对于100%的数据,1 ≤ N ≤ 5, 2 ≤ |S| ≤ 100000
Output对于每组数据,输出一行,内容是YES或者NO,代表是否存在题目要求的划分方案。
Sample Input
3 1248 2680 54174760
Sample Output
NO
1 #include <bits/stdc++.h> 2 using namespace std; 3 int T,n; 4 string s; 5 int sum; 6 int vis[1000005]; 7 int main(){ 8 scanf("%d",&T); 9 while(T--){ 10 cin >> s; 11 sum = 0; 12 memset(vis,0,sizeof(vis)); 13 for (int i = 0;i < s.length();++i){ 14 sum += (s[i] - '0'); 15 vis[sum] = 1; 16 } 17 bool jud = 1; 18 if (sum == 0) { 19 puts("YES"); 20 continue; 21 } 22 if (sum == 1 && s.length() == 1){ 23 puts("YES"); 24 continue; 25 } 26 for (int k = 2;k <= sum;++k){ 27 if (sum % k) continue; 28 if (k > 2 && k%2 == 0) continue; 29 int m = sum/k; 30 bool flag = 1; 31 for (int i = 1;i <= k;++i){ 32 if (!vis[i*m]){ 33 flag = 0; 34 break; 35 } 36 } 37 if (flag) { 38 jud = 0; 39 break; 40 } 41 } 42 if (!jud){ 43 puts("YES"); 44 }else puts("NO"); 45 } 46 }
C.子数组的和
给定一个包含N个整数的数组A = [A1, A2, ... AN],请你计算有多少个子数组B = [Ai, Ai+1, ... Aj] (i ≤ j) 满足B中所有整数的和小于K。
Input第一行包含两个整数N和K。
第二行包含N个整数A1, A2, ... AN。
对于30%的数据,1 ≤ N ≤ 1000
对于另外30%的数据,0 < Ai ≤ 100000
对于100%的数据,1 ≤ N ≤ 100000 -100000 ≤ Ai ≤ 100000
Output一个整数,代表答案。
Sample Input
4 -1 -2 1 -2 3
Sample Output
3
1 #include <bits/stdc++.h> 2 #define N 100005 3 using namespace std; 4 typedef long long ll; 5 int n,k,m; 6 ll a[N],p[N],c[N],cur[N]; 7 ll lowbit(ll x) {return x&-x;} 8 9 void add(ll x,ll w){ 10 while(x <= m){ 11 c[x] += w; 12 x += lowbit(x); 13 } 14 } 15 16 ll sum(ll x){ 17 ll ret = 0; 18 while(x){ 19 ret += c[x]; 20 x -= lowbit(x); 21 } 22 return ret; 23 } 24 25 ll index(ll w){ 26 ll l = 1,r = m; 27 while(l < r){ 28 ll mid = (l + r) >> 1; 29 if (p[mid] < w) l = mid+1; 30 else r = mid; 31 } 32 return (p[l] <= w) ? l : l-1; 33 } 34 35 int main(){ 36 scanf("%d%d",&n,&k); 37 for (int i = 1;i <= n;++i){ 38 scanf("%lld",a+i); 39 cur[i] = cur[i-1] + a[i]; 40 p[i] = cur[i]; 41 } 42 p[n+1] = 0; 43 sort(p+1,p+n+2); 44 m = unique(p+1,p+n+2) - (p+1); 45 add(index(0),1); 46 ll ans = 0; 47 for (int i = 1;i <= n;++i){ 48 //cout << i << " " << cur[i] - k << " " << index(cur[i]-k) << " " << i-sum(index(cur[i]-k)) << endl; 49 ans += i-sum(index(cur[i]-k)); 50 add(index(cur[i]),1); 51 } 52 printf("%lld\n",ans); 53 }