5月10日 Codeforces 实战记录。(0 -> 656)
 
第一次Codeforces试水,AC数7/8。Codeforces Round 944 (Div. 4) 
题解 A. B. E. 随题意模拟即可,不做赘述。
C. Clock and Strings 题意:判断环中两连线是否相交
分析:先锁定一条连线,再判断另一条边的两端点是否在连线同侧。
完整代码: 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 #include <bits/stdc++.h>  using  namespace  std;inline  int  read ()     int  x = 0 , f = 1 ; char  ch = getchar ();     while (ch < '0'  || ch > '9' ) { if (ch == '-' ) f = -1 ; ch = getchar (); }     while (ch >= '0'  && ch <= '9' ) { x = x * 10  + ch - 48 ; ch = getchar (); }     return  x * f; } int  main ()     int  t = read ();     while (t--){         int  a = read (), b = read (), c = read (), d = read ();                  int  mn = min (a, b), mx = max (a, b);                  bool  flag1 = 0 , flag2 = 0 ;                  if (mn < c && c < mx) flag1 = 1 ;         if (mn < d && d < mx) flag2 = 1 ;                  if (flag1 ^ flag2)             cout << "YES"  << '\n' ;         else  cout << "NO"  << '\n' ;     }     return  0 ; } 
补充解法 官方题解给出了一种很美妙的解法,直接用字符串模拟了两条连线的相对方位:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 #include <bits/stdc++.h>  using  namespace  std;inline  int  read ()     int  x = 0 , f = 1 ; char  ch = getchar ();     while (ch < '0'  || ch > '9' ) { if (ch == '-' ) f = -1 ; ch = getchar (); }     while (ch >= '0'  && ch <= '9' ) { x = x * 10  + ch - 48 ; ch = getchar (); }     return  x * f; } int  main ()     int  t = read ();     while (t--){         int  a = read (), b = read (), c = read (), d = read ();                  string s;         for  (int  i = 1 ; i <= 12 ; i++) {             if  (i == a || i == b) {s += "a" ;}             if  (i == c || i == d) {s += "b" ;}         }                  cout << (s == "abab"  || s == "baba"  ? "YES\n"  : "NO\n" );		     }     return  0 ; } 
D. Binary Cut 题意:通过剪切01序列,使其成为升序。
分析:先将所有01序列拆分成仅含0或仅含1的序列,再至多合并一对形如 0..0 与1..1 的序列,即出现 01 时 cnt--。
完整代码: 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 #include <bits/stdc++.h>  using  namespace  std;inline  int  read ()     int  x = 0 , f = 1 ; char  ch = getchar ();     while (ch < '0'  || ch > '9' ) { if (ch == '-' ) f = -1 ; ch = getchar (); }     while (ch >= '0'  && ch <= '9' ) { x = x * 10  + ch - 48 ; ch = getchar (); }     return  x * f; } int  main ()     int  t = read ();     while (t--){         string s; cin >> s;         int  cnt = 0 ;         char  last = ' ' ;         for (int  i = 0 ; i < s.length (); i++){             if (s[i] != last){                 cnt ++;                 last = s[i];             }         }         for (int  i = 0 ; i < s.length () - 1 ; i++){             if (s[i] == '0'  && s[i + 1 ] == '1' ){                 cnt--;                 break ;             }         }         cout << cnt << '\n' ;     }     return  0 ; } 
F. Circle Perimeter 题意:找出距离原点距离在 [r, r + 1) 内的整点个数。
分析:简化为4 * (第一象限与x轴正半轴格点数)
搜索时,对x轴上每一个i ,最高点 up 满足 i * i + up * up < (r + 1) * (r + 1),最低点 down 满足 i * i + down * down >= r * r,化简后 O(1) 找出 up down ,计数 up - down + 1 个格点即可。
完整代码: 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 #include <bits/stdc++.h>  #define  int long long using  namespace  std;inline  int  read ()      int  x = 0 , f = 1 ; char  ch = getchar ();     while  (ch < '0'  || ch > '9' ) { if  (ch == '-' ) f = -1 ; ch = getchar (); }     while  (ch >= '0'  && ch <= '9' ) { x = x * 10  + ch - 48 ; ch = getchar (); }     return  x * f; } signed  main ()      int  t = read ();     while  (t--) {         int  r = read ();         int  cnt = 0 ;         int  le = r * r;         int  ri = le + r + r + 1 ;         for  (int  i = 1 ; i <= r; i++) {             int  up = ceil (sqrt ((ri - i * i))) - 1 , down = ceil (sqrt ((le - i * i)));             cnt += up - down + 1 ;         }         cout << cnt * 4  << '\n' ;     }     return  0 ; } 
G. XOUR 题意:对二进制表示下,仅有最后两位不同的数记为一组,各组内排序。
实现:直接用map将除去后两位的值映射到优先队列自动排序即可。
完整代码: 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 #include <bits/stdc++.h>  using  namespace  std;inline  int  read ()     int  x = 0 , f = 1 ; char  ch = getchar ();     while (ch < '0'  || ch > '9' ) { if (ch == '-' ) f = -1 ; ch = getchar (); }     while (ch >= '0'  && ch <= '9' ) { x = x * 10  + ch - 48 ; ch = getchar (); }     return  x * f; } void  solve ()     int  n = read ();     vector<int > a (n)  ;     map<int , priority_queue<int , vector<int >, greater<int >>>mp;     for (int  i = 0 ; i < n; i++){         a[i] = read ();         mp[a[i] >> 2 ].push (a[i]);     }     for (int  i = 0 ; i < n; i++){         cout << mp[a[i] >> 2 ].top () << ' ' ;         mp[a[i] >> 2 ].pop ();     }     cout << '\n' ; } int  main ()     int  t = read ();     while (t--)         solve ();     return  0 ; }