题面很短,质量很好。
题目链接:https://codeforces.com/contest/1175
A:
给定n,k,有两种操作:1) n--,2) 当n%k==0时,可以n/=k。问最少多少步把n变成0。
傻逼题。
1 /* basic header */ 2 #include <bits/stdc++.h> 3 /* define */ 4 #define ll long long 5 #define dou double 6 #define pb emplace_back 7 #define mp make_pair 8 #define sot(a,b) sort(a+1,a+1+b) 9 #define rep1(i,a,b) for(int i=a;i<=b;++i) 10 #define rep0(i,a,b) for(int i=a;i<b;++i) 11 #define eps 1e-8 12 #define int_inf 0x3f3f3f3f 13 #define ll_inf 0x7f7f7f7f7f7f7f7f 14 #define lson curpos<<1 15 #define rson curpos<<1|1 16 /* namespace */ 17 using namespace std; 18 /* header end */ 19 20 int t; 21 22 int main() { 23 cin >> t; 24 while (t--) { 25 ll n, k; cin >> n >> k; 26 ll ans = 0; 27 while (n) { 28 if (n >= k) { 29 ans += n % k + 1; 30 n /= k; 31 } else { 32 ans += n % k; 33 n = 0; 34 } 35 } 36 cout << ans << endl; 37 } 38 return 0; 39 }
B:
给定一个函数f(x),该函数只有三种语句:
1) add。代表对当前的x+1。
2) for a(a是一个数字)。代表一个for循环和次数。
3) end。匹配for循环
现令x恒为0,对于给定的函数,输出计算结果。若中间结果或答案大于2^32-1,输出OVERFLOW!!!
一看就知道用stack处理。然而被const ll limit=1<<32这样的低级错误卡了智商,非常难受。
1 /* basic header */ 2 #include <bits/stdc++.h> 3 /* define */ 4 #define ll long long 5 #define dou double 6 #define pb emplace_back 7 #define mp make_pair 8 #define sot(a,b) sort(a+1,a+1+b) 9 #define rep1(i,a,b) for(int i=a;i<=b;++i) 10 #define rep0(i,a,b) for(int i=a;i<b;++i) 11 #define eps 1e-8 12 #define int_inf 0x3f3f3f3f 13 #define ll_inf 0x7f7f7f7f7f7f7f7f 14 #define lson curpos<<1 15 #define rson curpos<<1|1 16 /* namespace */ 17 using namespace std; 18 /* header end */ 19 20 const ll limit = 1LL << 32; 21 int n; 22 stack<ll>st; 23 24 int main() { 25 cin >> n; 26 ll curr = 0; 27 st.push(1LL); 28 while (n--) { 29 string s; cin >> s; 30 if (s == "add") 31 curr += st.top(); 32 else if (s == "for") { 33 ll x; cin >> x; 34 st.push(min(limit, x * st.top())); 35 } else if (s == "end") 36 st.pop(); 37 } 38 if (curr >= limit) puts("OVERFLOW!!!"); 39 else cout << curr << endl; 40 return 0; 41 }
C:
给定一维坐标系上的n个整点(升序给出)和一个整数k,现让你找到一个新整点,使得该整点到给定的n个整点的距离第k+1大值尽量小。
首先可以确定,这个整点不可能在n个整点之外,这不符合贪心的原则。
那么问题就很简单了:只要检查靠外的n-k对数:a[i]和a[i+k],找出靠得最近的一对并记录中点即可。
1 /* basic header */ 2 #include <bits/stdc++.h> 3 /* define */ 4 #define ll long long 5 #define dou double 6 #define pb emplace_back 7 #define mp make_pair 8 #define sot(a,b) sort(a+1,a+1+b) 9 #define rep1(i,a,b) for(int i=a;i<=b;++i) 10 #define rep0(i,a,b) for(int i=a;i<b;++i) 11 #define eps 1e-8 12 #define int_inf 0x3f3f3f3f 13 #define ll_inf 0x7f7f7f7f7f7f7f7f 14 #define lson curpos<<1 15 #define rson curpos<<1|1 16 /* namespace */ 17 using namespace std; 18 /* header end */ 19 20 const int maxn = 2e5 + 10; 21 int t; 22 23 int main() { 24 cin >> t; 25 while (t--) { 26 int n, k, a[maxn], minn = int_inf, ans = 0; 27 cin >> n >> k; 28 rep1(i, 1, n) cin >> a[i]; 29 rep1(i, 1, n - k) 30 if (minn > (a[i + k] - a[i] + 1) / 2) { 31 minn = (a[i + k] - a[i] + 1) / 2; 32 ans = (a[i + k] + a[i]) / 2; 33 } 34 printf("%d ", ans); 35 } 36 return 0; 37 }
D:
给定一个长度为n的序列和整数k,需要把该序列分割为k个非空连续子序列(每个元素都必须包含在某个子序列中),子序列编号为[1..k]。定义分割代价为Σ(a[i]*b[i]),a[i]为元素,b[i]为元素所在子序列编号。问最大分割代价为多少。
看上去很麻烦,其实是傻逼题,后缀和+sort秒杀。注意sort的时候不要包含a[1],因为序列每个元素都至少被算过一次。
1 /* basic header */ 2 #include <bits/stdc++.h> 3 /* define */ 4 #define ll long long 5 #define dou double 6 #define pb emplace_back 7 #define mp make_pair 8 #define sot(a,b) sort(a+1,a+1+b) 9 #define rep1(i,a,b) for(int i=a;i<=b;++i) 10 #define rep0(i,a,b) for(int i=a;i<b;++i) 11 #define eps 1e-8 12 #define int_inf 0x3f3f3f3f 13 #define ll_inf 0x7f7f7f7f7f7f7f7f 14 #define lson curpos<<1 15 #define rson curpos<<1|1 16 /* namespace */ 17 using namespace std; 18 /* header end */ 19 20 const int maxn = 3e5 + 10; 21 ll a[maxn]; 22 int n, k; 23 24 int main() { 25 cin >> n >> k; 26 rep1(i, 1, n) cin >> a[i]; 27 for (int i = n; i >= 1; i--) a[i] += a[i + 1]; 28 sort(a + 2, a + n + 1); reverse(a + 2, a + 1 + n); 29 ll ans = 0; 30 rep1(i, 1, k) ans += a[i]; 31 cout << ans << endl; 32 return 0; 33 }
E:
给定整数n,m。给定n个区间和m次查询,每次查询给出一个区间。对于每次查询,给出最少的使用区间个数,使得使用的区间能完全覆盖查询区间。
可以用rmq做,待补。
F:
待补。
G:
个位数人做出的神仙题。溜了溜了(