#596 div2 A-C 题解
签到题,有坑点
直接判断每种情况即可,注意a = 9, b = 1的情况。
1 #include <iostream> 2 using namespace std; 3 4 int main() 5 { 6 int a, b; 7 cin >> a >> b; 8 if(a == 9 && b == 1) cout << a << " 10" << endl; 9 else if(a > b) cout << "-1" << endl; 10 else if(a == b) cout << a << "1 " << b << "2" << endl; 11 else if(a + 1 == b) cout << a << "9 " << b << "0" << endl; 12 else cout << "-1" << endl; 13 return 0; 14 }
B2. TV Subscriptions (Hard Version)
简单版 暴力即可,没什么好说的。
困难版:
我先计算从1-d的答案,记录下来,定义两个指针L和R,L指向1,R指向d,使用map来记录购买节目的情况,定义temp来记录每次的答案
使map[a[l]]--;如果map[a[L]] == 0 则说明a[L]节目没有购买,temp--;然后L++;
先让R++,如果map[a[R]] == 0,说明需要购买,temp++;然后map[a[R]]++;
最后 ans = min(ans,temp)
1 #include <iostream> 2 #include <cstdio> 3 #include <map> 4 using namespace std; 5 const int N = 2e5 + 10; 6 7 int a[N]; 8 9 int main() 10 { 11 int t; 12 cin >> t; 13 while(t--) 14 { 15 map<int, int> m; 16 int n, k, d; 17 cin >> n >> k >> d; 18 for(int i = 1; i <= n; i++) cin >> a[i]; 19 int ans = 0; 20 for(int i = 1; i <= d; i++) 21 { 22 if(m[a[i]] == 0) ans++; 23 m[a[i]]++; 24 } 25 int tmp = ans; 26 int l = 1, r = d; 27 while(r < n) 28 { 29 m[a[l]]--; 30 if(m[a[l]] == 0) tmp--; 31 l++; r++; 32 if(m[a[r]] == 0) tmp++; 33 m[a[r]]++; 34 ans = min(ans, tmp); 35 } 36 cout << ans << endl; 37 } 38 return 0; 39 }
暴力没得说
n = (2^x1 + p) + (2^x2 + p ) + ...
转换一下 n - p * cnt = 2^x1 + 2^x2 + 2^x3;
很明显的暴力,枚举cnt,从1开始,边界是 (n - p * cnt) > 0,因为右边 > 0;
设 x = n - cnt * p;计算 x 的二进制下有几个1,如果1的个数 <= cnt 并且 x 是 >= cnt 的,说明cnt就是最小的解
至于为什么,
第一:把任意一个数转成二进制,例如 t = 1011 即 t = 2^0 + 2^1 + 2^3,可以看出每一项都不同,所以如果1的个数>cnt 的话,是不可能匹配的;
至于小于等于就可以是因为可以合并即 2^2 + 2^2 = 2^3
第二:x 必须大于等于cnt,由于是2的次方,即右边最小值就是cnt个2^0 = cnt,所以x 必须 大于等于 cnt.
1 #include <cstdio> 2 #include <cmath> 3 #include <iostream> 4 using namespace std; 5 6 int n, p; 7 8 //计算x中有几个1 9 int cal(int x) 10 { 11 int res = 0; 12 while(x) 13 { 14 if(x & 1) res++; 15 x>>=1; 16 } 17 return res; 18 } 19 20 int main() 21 { 22 cin >> n >> p; 23 int ans = 1; 24 while((n - ans * p) > 0) 25 { 26 int x = n - ans * p; 27 int cnt = cal(x); 28 if(cnt <= ans && x >= ans) 29 { 30 cout << ans << endl; 31 return 0; 32 } 33 ans++; 34 } 35 cout << "-1" << endl; 36 return 0; 37 }