ABC 354 (atcoder beginer 354) D、E、F

congmingyige發表於2024-05-20

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.

我倒覺得D題AC數目比E題少很不正常。D題是非常簡單的模擬題。我賽後用chatgpt 4o去解答E題,獲得了正確的答案。

chatgpt:甚至題目直接複製貼上就可以了,即使有格式上的錯誤也可以。

重複試了兩次,都能AC。

為什麼會出現這樣的情況?:1. 有以前類似的題目? 2 網路上的搜尋功能? 3 chatgpt就是牛逼。

 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 */

相關文章