Codeforces Round #606 (Div. 2, based on Technocup 2020 Elimination Round 4)
A. Happy Birthday, Polycarp!
对1~9枚举n以内的数即可
#include <bits/stdc++.h> using namespace std; int t, n; typedef long long ll; int main() { ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); cin >> t; while( t-- ){ int ans = 0; cin >> n; for( int i=1; i<=9; i++ ){ ll p = i; while( p<=n ){ ans ++; p *= 10; p += i; } } cout << ans <<endl; } return 0; }
B.Make Them Odd
把所有的偶数放到set里,利用set的自动排序,每次取第一个数,让他除以2,ans同时+1,然后判断除以2之后的数是否是偶数,是偶数就再放入set。
因为这里因为set是从小到大排序,所以存储负值即可。
#include <bits/stdc++.h> using namespace std; const int maxn = 2e5 + 5; int t, n; int main() { ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); cin >> t; while( t-- ){ set<int> c; cin >> n; int x, ans = 0; for( int i=0; i<n; i++ ){ cin >> x; if( (x&1)==0 ) c.insert(-x); } while( c.size() ){ ans ++; int p = -(*c.begin()); c.erase(-p); p >>= 1; if( p%2==0 ) c.insert(-p); } cout << ans << endl; } return 0; }
C.As Simple as One and Two
two和one都有'o'字母,枚举'o'的位置,判断向前能否构成two,向后能否构成one,如果能每次删掉'o'即可。考虑到可能存在个三种特殊情况twone,ooone,twooo。判断是否是这三种情况,
第一种情况就只记一次,第二种情况就不删'o'改删'n'或'e'都可,第三种情况也是改删't'或'w'都可。
#include <bits/stdc++.h> using namespace std; int t; string s; int main() { // freopen("in.txt", "r", stdin); ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); cin >> t; while( t-- ){ vector<int> pos; cin >> s; int len = s.size(); int ans = 0; for( int i=0; i<len; i++ ){ if( s[i]=='o' ){ bool f1=0, f2=0; if( i+2<len && s[i+1]=='n' && s[i+2]=='e' ) f1 = 1; if( i-2>=0 && s[i-1]=='w' && s[i-2]=='t' ) f2 = 1; if( f1 ){ ans ++; if( i-1>=0 && s[i-1]=='o' ) pos.push_back(i+2); else pos.push_back(i+1); } if( f2 ){ ans ++; if( i+1<len && s[i+1]=='o' ) pos.push_back(i); else pos.push_back(i+1); } if( f1&&f2 ) ans --, pos.pop_back(); } } cout << ans <<endl; for( int i=0; i<ans; i++ ){ if( i ) cout << " "; cout << pos[i]; } cout << endl; } return 0; }
UPD:
E.Two Fairs
分别对a, b两点进行bfs,对a能到达的点标记为visA[],对b能到达的点标记为visB[],一开始把a,b两点都标记visA[a] = visB[a] = visA[b] = visB[b] = 1.然后再bfs。
最后对n个点遍历,统计只能被a到达不能由b到达的点的个数num1,和只能由b到达的点个数num2,最后答案为num1*num2。
1 #include <bits/stdc++.h> 2 3 using namespace std; 4 5 const int maxn = 2e5 + 5; 6 const int maxe = 5e5 + 5; 7 typedef long long ll; 8 int t, n, m, a, b, num1, num2; 9 struct edge{ 10 int to, next; 11 } ed[maxe<<1]; 12 int head[maxn], tot; 13 bool visA[maxn], visB[maxn]; 14 inline void init(){ 15 for( int i=0; i<=n; i++ ){ 16 head[i] = -1; 17 visA[i] = visB[i] = 0; 18 } 19 num1 = num2 = 0; 20 tot = 1; 21 } 22 23 inline void add( int u, int v ){ 24 ed[++tot].to = v; ed[tot].next = head[u]; head[u] = tot; 25 ed[++tot].to = u; ed[tot].next = head[v]; head[v] = tot; 26 } 27 28 inline void bfs( int st, bool f ){ 29 queue<int> q; 30 q.push(st); 31 while( q.size() ){ 32 int x = q.front(); 33 q.pop(); 34 for( int i=head[x]; ~i; i=ed[i].next ){ 35 int y = ed[i].to; 36 if( f && visA[y] ) continue; 37 else if( !f && visB[y] ) continue; 38 if( f ) visA[y] = 1; 39 else visB[y] = 1; 40 q.push(y); 41 } 42 } 43 } 44 45 int main() 46 { 47 // freopen("in.txt", "r", stdin); 48 ios::sync_with_stdio(0); 49 cin.tie(0); cout.tie(0); 50 cin >> t; 51 while( t-- ){ 52 cin >> n >> m >> a >> b; 53 init(); 54 for( int i=0; i<m; i++ ){ 55 int u, v; 56 cin >> u >> v; 57 add( u, v ); 58 } 59 visA[a] = visB[b] = visA[b] = visB[a] = 1; 60 bfs(a, 1); bfs(b, 0); 61 for( int i=1; i<=n; i++ ){ 62 if( visA[i]&&!visB[i] ) num1 ++; 63 else if( !visA[i]&&visB[i] ) num2 ++; 64 } 65 ll res = 1ll* num1*num2; 66 cout << res << endl; 67 } 68 69 return 0; 70 }