D
检查:
1. 有可能是推导式有问题,比如-/+写错
2. x,y A、B、C、D 顺序可能搞反了
不要盲目调试,先用人眼看一下代码的情况,找一下错误
很简单的找规律的题目。
很不能理解过的人,就这些。
x方向,y方向,都是4行/列,一个规律的循环。
求(0,0)到(x,y)中的黑色块:
第0-3行分别求出黑色块数目:通过列的循环
然后行的循环求和
cal(C,D) - cal(A,D) - cal(C,B) + cal(A,B) 这个很熟悉吧。就是:
为了方便求,先把x、y坐标的数值都转为正整数。
1 /* 2 检查; 3 1. 有可能是推导式有问题,比如-/+写错 4 2. x,y A、B、C、D 顺序可能搞反了 5 不要盲目调试,先用人眼看一下代码的情况,找一下错误 6 */ 7 #include <cstdio> 8 #include <cstdlib> 9 #include <cstring> 10 #include <cmath> 11 #include <cstdbool> 12 #include <string> 13 #include <algorithm> 14 #include <iostream> 15 #include <sstream> 16 #include <ctime> 17 #include <stack> 18 #include <vector> 19 #include <queue> 20 #include <set> 21 #include <map> 22 #include <array> 23 #include <bitset> 24 using namespace std; 25 #define LL long long 26 #define ULL unsigned long long 27 28 const LL mod_1=1e9+7; 29 const LL mod_2=998244353; 30 31 const double eps_1=1e-5; 32 const double eps_2=1e-10; 33 34 const int maxn=2e5+10; 35 36 ///x 0 to 4 : y value 37 LL f[4][4]={ 38 {2,1,2,1}, 39 {1,2,1,2}, 40 {0,1,0,1}, 41 {1,0,1,0} 42 }; 43 LL f_loop[4]={6,6,2,2}; 44 45 LL v[4]; 46 47 LL cal(LL x, LL y) 48 { 49 v[0]=v[1]=v[2]=v[3]=0; 50 51 LL x_mod = x%4; 52 LL y_mod = y%4; 53 LL x_loop = x/4; 54 LL y_loop = y/4; 55 LL i,j,result=0; 56 57 for (i=0;i<4;i++) 58 v[i]+=y_loop * f_loop[i]; 59 for (i=0;i<4;i++) 60 { 61 for (j=0;j<y_mod;j++) 62 v[i]+=f[i][j]; 63 } 64 LL f_loop_cnt=v[0]+v[1]+v[2]+v[3]; 65 66 result += f_loop_cnt * x_loop; 67 68 for (i=0;i<x_mod;i++) 69 result+=v[i]; 70 71 72 return result; 73 } 74 75 int main() 76 { 77 LL A,B,C,D,temp; 78 79 if (0) 80 { 81 /* 82 cout<<cal(1,1)<<endl; 83 cout<<cal(2,2)<<endl; 84 cout<<cal(3,3)<<endl; 85 cout<<cal(4,4)<<endl; 86 */ 87 88 //cout<<cal(1,2)<<endl; 89 //cout<<cal(2,1)<<endl; 90 91 //cout<<cal(1,6)<<endl; 92 93 //cout<<cal(2,5)<<endl; 94 95 cout<<cal(5,7)<<endl; 96 cout<<cal(5,2)<<endl; 97 cout<<cal(3,7)<<endl; 98 cout<<cal(3,2)<<endl; 99 100 101 return 0; 102 } 103 104 105 cin>>A>>B>>C>>D; 106 107 if (A<0) 108 { 109 temp=(-A+4)/4; 110 A+=temp*4; 111 C+=temp*4; 112 } 113 114 if (B<0) 115 { 116 temp=(-B+4)/4; 117 B+=temp*4; 118 D+=temp*4; 119 } 120 121 122 123 124 125 cout<< cal(C,D) - cal(A,D) - cal(C,B) + cal(A,B); 126 127 return 0; 128 }
E
这么多人对,有点怀疑是不是AI做的。
我用chatgpt 4-o(现在免费的),居然一发入魂,AC了。
我在CF提出了我的疑问。也看到有人跟我提出类似的疑问。
Panasonic Programming Contest 2024(AtCoder Beginner Contest 354) Announcement - Codeforces
So many people solve E in the competition. I doubt if some of them using chatgpt. I get AC of problem E using code generated by chatgpt 4o. The code is as follows.
It is more stranger that the people solve E are 2223, D are 2092. D、F are quite a lot easy compare with E. D is quite easy by the way, but only 2092 people solve it. I doubt if some of them using **chatgpt** by solving proble **E**. I get AC of problem E using code generated by chatgpt 4o.
1 #include <iostream> 2 #include <vector> 3 #include <unordered_map> 4 5 using namespace std; 6 7 struct Card { 8 int front; 9 int back; 10 }; 11 12 int N; 13 vector<Card> cards; 14 unordered_map<int, bool> memo; 15 16 bool canWin(int state) { 17 if (memo.count(state)) return memo[state]; 18 19 // Check all pairs of cards 20 for (int i = 0; i < N; ++i) { 21 if (!(state & (1 << i))) continue; // Card i is already removed 22 for (int j = i + 1; j < N; ++j) { 23 if (!(state & (1 << j))) continue; // Card j is already removed 24 if (cards[i].front == cards[j].front || cards[i].back == cards[j].back) { 25 int newState = state & ~(1 << i) & ~(1 << j); 26 if (!canWin(newState)) { 27 memo[state] = true; 28 return true; 29 } 30 } 31 } 32 } 33 memo[state] = false; 34 return false; 35 } 36 37 int main() { 38 cin >> N; 39 cards.resize(N); 40 for (int i = 0; i < N; ++i) { 41 cin >> cards[i].front >> cards[i].back; 42 } 43 44 int initialState = (1 << N) - 1; // All cards are initially on the table 45 if (canWin(initialState)) { 46 cout << "Takahashi" << endl; 47 } else { 48 cout << "Aoki" << endl; 49 } 50 51 return 0; 52 }
=========================================================================
=========================================================================
=========================================================================
18这个数字,想到2^18(<1e6)复杂度?
F
看题/做题顺序:
a. E没有什么想法的话,这种题(如果)难做,而且时间耗在那,比如先做其它题目
b. 应该先看一下F题的题意的,也许比E好做呢?
c. 特别是1000人做对,就知道题目可能相对容易做,更加需要在第40分钟-第1小时的时候,花5分钟,看一下题意
d. 如果留30-40分钟做这道题,那么会很舒服,大概率能做出来。
从第1位置到第x位置递增,LIS的长度,从第n位置到第x位置递减,LIS的长度,相加,如果是对的,它就可以用
因为T<=2e5,a[i]<=1e9,LIS的树状数组写法应该是很不好写的。
那么用二分的写法。
善用lower_bound很重要。
对于反过来求从大到小的LIS,数值改为相反的负值就行了,即相当于求从小到大的LIS->代码设计上的巧妙。
这个例子,说明用lower_bound(>=),而不是upper_bound(>)。
1 10 2 9 3 2 3 4 1 1 1 5 6 7
1 /* 2 题解:从第1位置到第x位置递增,LIS的长度,从第n位置到第x位置递减,LIS的长度,相加,如果是对的,它就可以用 3 */ 4 #include <cstdio> 5 #include <cstdlib> 6 #include <cstring> 7 #include <cmath> 8 #include <cstdbool> 9 #include <string> 10 #include <algorithm> 11 #include <iostream> 12 #include <sstream> 13 #include <ctime> 14 #include <stack> 15 #include <vector> 16 #include <queue> 17 #include <set> 18 #include <map> 19 #include <array> 20 #include <bitset> 21 using namespace std; 22 #define LL long long 23 #define ULL unsigned long long 24 25 const LL mod_1=1e9+7; 26 const LL mod_2=998244353; 27 28 const double eps_1=1e-5; 29 const double eps_2=1e-10; 30 31 const int maxn=2e5+10; 32 33 int a[maxn], f[maxn], pos1[maxn], pos2[maxn]; 34 vector<int> vec; 35 36 int main() 37 { 38 int T,n,m,cnt,u,i,j; 39 scanf("%d",&T); 40 while (T--) 41 { 42 scanf("%d",&n); 43 for (i=0;i<n;i++) 44 scanf("%d", &a[i]); 45 46 m=0; 47 for (i=0;i<n;i++) 48 { 49 j = lower_bound(f, f+m, a[i]) - f; 50 51 pos1[i]=j; 52 53 f[j] = a[i]; 54 if (j==m) 55 m++; 56 } 57 58 /* 59 for (i=0;i<n;i++) 60 printf("%d ", pos1[i]); 61 printf("\n"); 62 */ 63 64 65 for (i=0;i<n;i++) 66 a[i]=-a[i]; 67 m=0; 68 for (i=n-1;i>=0;i--) 69 { 70 j = lower_bound(f, f+m, a[i]) - f; 71 72 pos2[i]=j; 73 74 f[j] = a[i]; 75 if (j==m) 76 m++; 77 } 78 79 80 u=0; 81 for (i=0;i<n;i++) 82 u = max(u, pos1[i]+pos2[i]); 83 84 vec.clear(); 85 cnt=0; 86 for (i=0;i<n;i++) 87 if (pos1[i]+pos2[i]==u) 88 { 89 cnt++; 90 vec.push_back(i); 91 } 92 93 printf("%d\n",cnt); 94 for (i=0;i<cnt;i++) 95 { 96 printf("%d",vec[i]+1); 97 if (i==cnt-1) 98 printf("\n"); 99 else 100 printf(" "); 101 } 102 103 104 } 105 106 107 108 return 0; 109 } 110 /* 111 10 112 5 113 1 2 3 4 5 114 5 115 1 2 3 4 5 116 5 117 5 4 3 2 1 118 5 119 1 2 3 4 5 120 5 121 1 1 1 1 1 122 5 123 1 2 3 4 5 124 125 126 127 10 128 9 129 2 3 4 1 1 1 5 6 7 130 */