atcoder regular 175 題解 A-C D還未解決

congmingyige發表於2024-03-29

A

要麼所有人全部做左邊的筷子,要麼全部右邊的筷子。依次處理。

大家按照順序拿筷子,如果成立,當前的人,所需方向的筷子肯定沒拿。如果所需方向的反方向的筷子被拿了,就結果*2(第一選擇方向可以任選);反而,肯定要求第一選擇方向是所需方向,就結果*1。

 1 #include <cstdio>
 2 #include <cstdlib>
 3 #include <cstring>
 4 #include <cmath>
 5 #include <cstdbool>
 6 #include <string>
 7 #include <algorithm>
 8 #include <iostream>
 9 #include <sstream>
10 #include <ctime>
11 #include <stack>
12 #include <vector>
13 #include <queue>
14 #include <set>
15 #include <map>
16 using namespace std;
17 #define ll long long
18 #define ull unsigned long long
19 
20 
21 const ll mod=998244353;
22 
23 const double eps_1=1e-5;
24 const double eps_2=1e-10;
25 
26 const int maxn=2e5+10;
27 
28 bool vis[maxn];
29 char str[maxn];
30 int n,fx,a[maxn];
31 ll result=0;
32 
33 void handle()
34 {
35     int i,d,left,right,mode;
36     ll ans=1;
37 
38     for (i=1;i<=n;i++)
39     {
40         d=a[i];
41 
42         left=d-1;
43         if (left==0)
44             left=n;
45         right=d+1;
46         if (right==n+1)
47             right=1;
48 
49         if (str[d]=='L')
50             mode=1;
51         else if (str[d]=='R')
52             mode=2;
53         else
54             mode=0;
55 
56         if (fx==1)
57         {
58             if (!vis[right] && mode==2)
59                 return;
60             if (vis[right] && mode==0)
61                 ans=ans*2%mod;
62         }
63         else
64         {
65             if (!vis[left] && mode==1)
66                 return;
67             if (vis[left] && mode==0)
68                 ans=ans*2%mod;
69         }
70         vis[d]=1;
71     }
72 
73     result=(result+ans)%mod;
74 }
75 
76 int main()
77 {
78     int i;
79     scanf("%d",&n);
80     for (i=1;i<=n;i++)
81         scanf("%d",&a[i]);
82     scanf("%s",str+1);
83 
84     for (fx=0;fx<=1;fx++)
85     {
86         memset(vis,0,sizeof(vis));
87         handle();
88     }
89 
90     printf("%lld", result);
91 
92     return 0;
93 }

B

左括號,右括號數目= x,y

1. abs(x-y)/2,肯定就是修改的(->) 、 )->( 的數目。如果是)->(,一開始把“最左邊”的這些')'改成’('。

2. (->) 、 )->( 花費為B,也可以花費為2*A的方式解決

3. 從左到右,記錄 '(' - ')' 的數目,找出有')‘,使得 '(' - ')' = -1的情況,這時候需要B/2A了。')‘->'('後,'(' - ')'變為1。記錄最少需要B/2A的次數。

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <cstdbool>
#include <string>
#include <algorithm>
#include <iostream>
#include <sstream>
#include <ctime>
#include <stack>
#include <vector>
#include <queue>
#include <set>
#include <map>
using namespace std;
#define ll long long
#define ull unsigned long long

const ll mod_1=1e9+7;
const ll mod_2=998244353;

const double eps_1=1e-5;
const double eps_2=1e-10;

const int maxn=1e6+10;

char str[maxn];


int main()
{
    int n,len,i;
    ll cha=0,jia_cnt=0,cnt_lower_zero=0,a,b;
    //ll result=0;
    scanf("%d%lld%lld",&n,&a,&b);
    scanf("%s",str);
    len=strlen(str);

    for (i=0;i<len;i++)
        if (str[i]=='(')
            cha++;
        else
            cha--;
    if (cha<0)
        jia_cnt=abs(cha);
    cha=abs(cha)/2;


    for (i=0;i<len;i++)
    {
        if (str[i]==')')
            jia_cnt--;
        else
            jia_cnt++;
        if (jia_cnt<0)
        {
            jia_cnt=1;
            cnt_lower_zero++;
        }
    }
    if (a>b*2)
        printf("%lld",(cha+cnt_lower_zero*2) *b );
    else
        printf("%lld",cha*b + cnt_lower_zero*a );

    return 0;
}
/*
(((((((((
)))))


3 2 2
((((((

3 10 2
((((((

3 2 10
((((((

3 2 2
))))))

3 2 10
))))))





3 2 10
)))(((

3 10 2
)))(((

3 2 2
)))(((
*/

C

遇到這種題很頭疼,很容易找不到錯誤的地方,製造不出可以找到錯誤的樣例。

這種題目應該先多製造幾個樣例,然後把一些條理理清楚了再寫會比較好

官方題解看著有點暈,也看到寫得特別短的程式碼,有點不理解……

我的是,把這些分為[l1,r1] [l2,r2] [l3,r3] ... [lk,rk]的區間,它們互不交集。然後區間有升有降。

如果l_{i-1} -> l_{i} -> l_{i+1} 是降、升的趨勢,那麼這個區間的數值應該選擇r_{i},還有最左邊和最右邊的區間要做特殊處理,其它都選擇l_{i}。

對於一個區間,它相對於上個區間是升的話,然後這個區間最左邊的幾個數值可以往上個區間那個靠,這是為了讓字典序最小,只要滿足條件即可。

同理,對於一個區間,它相對於下個區間是降的話,然後這個區間最右邊的幾個數值可以往下個區間那個靠,這是為了讓字典序最小,只要滿足條件即可。

  1 /*
  2 1 製造比較小的隨機資料
  3 10以內的
  4 2 然後用std程式跑結果
  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 using namespace std;
 23 
 24 const double eps_1=1e-5;
 25 const double eps_2=1e-10;
 26 
 27 const int maxn=5e5+10;
 28 
 29 
 30 
 31 
 32 int l[maxn],r[maxn],v[maxn],result[maxn];
 33 int ql[maxn],qr[maxn],range[maxn];
 34 
 35 int main()
 36 {
 37     int inf=1e9+10;
 38     int n,i,j,k,o,ll=-inf,rr=inf,cnt=1,temp;
 39     range[0]=0;
 40     scanf("%d",&n);
 41     for (i=1;i<=n;i++)
 42     {
 43         scanf("%d%d",&l[i],&r[i]);
 44 
 45         if (r[i]<ll || l[i]>rr)
 46         {
 47             range[cnt]=i-1;
 48             ql[cnt]=ll;
 49             qr[cnt]=rr;
 50 
 51             ll=l[i];
 52             rr=r[i];
 53             cnt++;
 54         }
 55 
 56         ll=max(ll, l[i]);
 57         rr=min(rr, r[i]);
 58     }
 59 
 60     ql[cnt]=ll;
 61     qr[cnt]=rr;
 62     range[cnt]=n;
 63 
 64 
 65 
 66 
 67     for (i=1;i<=cnt;i++)
 68         v[i]=ql[i];
 69 
 70     if (cnt!=1)
 71     {
 72 
 73         i=1;
 74         while (i<cnt)
 75         {
 76             if (i<cnt && ql[i]>ql[i+1])
 77             {
 78                 while (ql[i]>ql[i+1])
 79                     i++;
 80                 if (i!=cnt)
 81                     v[i]=qr[i];
 82             }
 83             i++;
 84         }
 85 
 86         if (ql[1]<ql[2])
 87             v[1]=qr[1];
 88 
 89         if (ql[cnt-1]>ql[cnt])
 90             v[cnt]=qr[cnt];
 91     }
 92 
 93 
 94     for (i=1 ;i<=cnt;i++)
 95     {
 96         if (i!=1 && v[i]>v[i-1])
 97         {
 98             temp = l[ range[i-1]+1 ];
 99             for (o=range[i-1]+1 ; o<=range[i] ; o++)
100             {
101                 if (l[o]>temp)
102                     temp=l[o];
103                 if (temp==v[i])
104                     break;
105                 result[o]=temp;
106             }
107         }
108         else
109             o=range[i-1]+1;
110 
111         if (i!=cnt && v[i]>v[i+1])
112         {
113             temp = v[i+1];
114             for (k=range[i] ; k>=o ; k--)
115             {
116                 if (l[k]>temp)
117                     temp=l[k];
118                 if (temp==v[i])
119                     break;
120                 result[k]=temp;
121             }
122         }
123         else
124             k=range[i];
125 
126         for (j=o ; j<=k ; j++)
127             result[j]=v[i];
128 
129     }
130 
131     for (i=1;i<=n;i++)
132     {
133         printf("%d",result[i]);
134         if (i!=n)
135             printf(" ");
136     }
137 
138     return 0;
139 }
140 /*
141 15
142 5 29
143 9 28
144 15 19
145 4 26
146 7 23
147 10 13
148 12 25
149 3 11
150 6 17
151 1 21
152 24 27
153 2 8
154 14 18
155 20 22
156 16 30
157 
158 
159 
160 15 15 15 12 12 12 12 11 11 11 24 8 14 20 20
161 
162 
163 
164 
165 
166 5
167 50 60
168 40 50
169 30 40
170 20 30
171 10 20
172 
173 5
174 10 20
175 20 30
176 30 40
177 40 50
178 50 60
179 
180 2
181 10 30
182 40 60
183 
184 2
185 40 60
186 10 30
187 
188 5
189 100 200
190 300 400
191 500 600
192 50 70
193 20 40
194 
195 */

  1 /*
  2 1 製造比較小的隨機資料
  3 10以內的
  4 2 然後用std程式跑結果
  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 using namespace std;
 23 
 24 const double eps_1=1e-5;
 25 const double eps_2=1e-10;
 26 
 27 const int maxn=5e5+10;
 28 
 29 
 30 int l[maxn],r[maxn],v[maxn],result[maxn];
 31 int ql[maxn],qr[maxn],range[maxn];
 32 
 33 int main()
 34 {
 35     int inf=1e9+10;
 36     int n,i,j,ll=-inf,rr=inf,cnt=0,temp;
 37     range[0]=0;
 38     scanf("%d",&n);
 39     for (i=1;i<=n;i++)
 40     {
 41         scanf("%d%d",&l[i],&r[i]);
 42 
 43         if (r[i]<ll || l[i]>rr)
 44         {
 45             ++cnt;
 46             range[cnt]=i-1;
 47             ql[cnt]=ll;
 48             qr[cnt]=rr;
 49 
 50             ll=-inf,rr=inf;
 51         }
 52 
 53         ll=max(ll, l[i]);
 54         rr=min(rr, r[i]);
 55     }
 56 
 57     ++cnt;
 58     range[cnt]=n;
 59     ql[cnt]=ll;
 60     qr[cnt]=rr;
 61 
 62 
 63     for (i=1;i<=cnt;i++)
 64         if (cnt!=1 && ((i==1 || ql[i]<ql[i-1]) && (i==cnt || ql[i]<ql[i+1])))
 65             v[i]=qr[i];
 66         else
 67             v[i]=ql[i];
 68     j=1;
 69     for (i=1;i<=n;i++)
 70     {
 71         result[i]=v[j];
 72         if (j!=cnt && i==range[j])
 73             j++;
 74     }
 75 
 76     for (i=1;i<=cnt;i++)
 77     {
 78         //asc
 79         if (i!=1 && v[i]>v[i-1])
 80         {
 81             j=range[i-1]+1;
 82             temp = v[i-1];
 83             while (temp<ql[i])
 84             {
 85                 temp=max(temp,l[j]);
 86                 result[j]=temp;
 87                 j++;
 88             }
 89         }
 90 
 91         //des
 92         if (i!=cnt && v[i]>v[i+1])
 93         {
 94             j=range[i];
 95             temp=v[i+1];
 96             while (temp<ql[i])
 97             {
 98                 temp=max(temp,l[j]);
 99                 result[j]=temp;
100                 j--;
101             }
102         }
103     }
104 
105     for (i=1;i<=n;i++)
106     {
107         printf("%d",result[i]);
108         if (i!=n)
109             printf(" ");
110     }
111 
112     return 0;
113 }
114 /*
115 15
116 5 29
117 9 28
118 15 19
119 4 26
120 7 23
121 10 13
122 12 25
123 3 11
124 6 17
125 1 21
126 24 27
127 2 8
128 14 18
129 20 22
130 16 30
131 
132 
133 
134 15 15 15 12 12 12 12 11 11 11 24 8 14 20 20
135 
136 
137 
138 
139 
140 5
141 50 60
142 40 50
143 30 40
144 20 30
145 10 20
146 
147 5
148 10 20
149 20 30
150 30 40
151 40 50
152 50 60
153 
154 2
155 10 30
156 40 60
157 
158 2
159 40 60
160 10 30
161 
162 5
163 100 200
164 300 400
165 500 600
166 50 70
167 20 40
168 
169 */

把樣例裡的數值離散化,方便看得清

  1 #include <cstdio>
  2 #include <cstdlib>
  3 #include <cstring>
  4 #include <cmath>
  5 #include <cstdbool>
  6 #include <string>
  7 #include <algorithm>
  8 #include <iostream>
  9 #include <sstream>
 10 #include <ctime>
 11 #include <stack>
 12 #include <vector>
 13 #include <queue>
 14 #include <set>
 15 #include <map>
 16 using namespace std;
 17 #define ll long long
 18 #define ull unsigned long long
 19 
 20 const ll mod_1=1e9+7;
 21 const ll mod_2=998244353;
 22 
 23 const double eps_1=1e-5;
 24 const double eps_2=1e-10;
 25 
 26 const int maxn=30+10;
 27 
 28 
 29 int a[maxn],b[maxn],c[maxn],r[maxn];
 30 map<int,int> map_1;
 31 
 32 
 33 int main()
 34 {
 35     int n,i,j=0;
 36     scanf("%d",&n);
 37     for (i=1;i<=n;i++)
 38     {
 39         scanf("%d%d",&a[i],&b[i]);
 40         c[i*2-1]=a[i];
 41         c[i*2]=b[i];
 42     }
 43     for (i=1;i<=n;i++)
 44         scanf("%d",&r[i]);
 45     sort(c+1,c+2*n+1);
 46     c[0]=-1;
 47     for (i=1;i<=2*n;i++)
 48         if (c[i]!=c[i-1])
 49         {
 50             j++;
 51             map_1[ c[i] ] = j;
 52         }
 53 
 54     for (i=1;i<=n;i++)
 55         printf("%d %d\n",map_1[ a[i] ], map_1[ b[i] ]);
 56     printf("\n\n\n");
 57     for (i=1;i<=n;i++)
 58         printf("%d ",map_1[ r[i] ]);
 59 
 60     return 0;
 61 }
 62 /*
 63 5 29
 64 9 28
 65 15 19
 66 4 26
 67 7 23
 68 10 13
 69 12 25
 70 3 11
 71 6 17
 72 1 21
 73 24 27
 74 2 8
 75 14 18
 76 20 22
 77 16 30
 78 
 79 
 80 
 81 
 82 5 29
 83 9 28
 84 15 19
 85 4 26
 86 7 23
 87 10 13
 88 12 25
 89 3 11
 90 6 17
 91 1 21
 92 24 27
 93 2 8
 94 14 18
 95 20 22
 96 16 30
 97 
 98 
 99 
100 15 15 15 12 12 12 12 11 11 11 24 8 14 20 20
101 */

建立小的資料

 1 /*
 2 10以內資料
 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 using namespace std;
20 #define ll long long
21 #define ull unsigned long long
22 
23 const ll mod_1=1e9+7;
24 const ll mod_2=998244353;
25 
26 const double eps_1=1e-5;
27 const double eps_2=1e-10;
28 
29 const int maxn=2e5+10;
30 
31 
32 
33 
34 
35 
36 int main()
37 {
38     int n=30,range=30,i,x,y;
39     srand((int)time(0));
40     printf("%d\n",n);
41 
42     for (i=1;i<=n;i++)
43     {
44         x=rand()%range;
45         y=rand()%range;
46         if (x>y)
47             swap(x,y);
48         printf("%d %d\n",x,y);
49     }
50 
51 
52     return 0;
53 }

暴力用程式獲取小資料的輸出結果

比如資料l_i,r_i在1-x範圍內

然後結果可以是(r_i - l_i + 1) ^n種,然後在最小化的情況下,最小序列的輸出

複雜度(r_i - l_i + 1) ^n

9個l_i-r_i範圍為1-10的資料

12個l_i-r_i範圍為1-5的資料

17個l_i-r_i範圍為1-3的資料

看著也勉強還行

如果真要到這種地步的話

如果是賽後,對著test case或者是用別人的std程式碼跑一些樣例出來

D

ABC165_F_LIS_on_Tree

LIS,二分,當前數值修改到這個當下最長子序列對應的位置

樹,dfs,當前位置,前修改,最後修改回來

  1 #include <cstdio>
  2 #include <cstdlib>
  3 #include <cstring>
  4 #include <cmath>
  5 #include <cstdbool>
  6 #include <string>
  7 #include <algorithm>
  8 #include <iostream>
  9 #include <sstream>
 10 #include <ctime>
 11 #include <stack>
 12 #include <vector>
 13 #include <queue>
 14 #include <set>
 15 #include <map>
 16 using namespace std;
 17 #define LL long long
 18 #define ULL unsigned long long
 19 
 20 const LL mod_1=1e9+7;
 21 const LL mod_2=998244353;
 22 
 23 const double eps_1=1e-5;
 24 const double eps_2=1e-10;
 25 
 26 const int maxn=2e5+10;
 27 
 28 int a[maxn], f[maxn], result[maxn], cnt=0;
 29 
 30 vector<int> adj[maxn], child[maxn];
 31 bool hap[maxn];
 32 
 33 void find_child(int d)
 34 {
 35     hap[d]=1;
 36     for (auto chi:adj[d])
 37         if (!hap[chi])
 38         {
 39             child[d].push_back(chi);
 40             find_child(chi);
 41         }
 42 }
 43 
 44 void dfs(int d)
 45 {
 46     int pre_f_ith, pre_cnt = cnt;
 47 
 48     int ith = lower_bound(f, f+cnt, a[d]) - f;
 49     pre_f_ith = f[ith];
 50     f[ith] = a[d];
 51     if (ith>=cnt)
 52         cnt++;
 53     result[d] = cnt;
 54 
 55     for (auto chi:child[d])
 56         dfs(chi);
 57 
 58     cnt = pre_cnt;
 59     f[ith] = pre_f_ith;
 60 }
 61 
 62 int main()
 63 {
 64     int n,i,x,y;
 65     memset(hap,0,sizeof(hap));
 66     scanf("%d",&n);
 67     for (i=1;i<=n;i++)
 68         scanf("%d",&a[i]);
 69     for (i=1;i<n;i++)
 70     {
 71         scanf("%d%d",&x,&y);
 72         adj[x].push_back(y);
 73         adj[y].push_back(x);
 74     }
 75 
 76     f[0]=0;
 77     find_child(1);
 78     dfs(1);
 79 
 80     for (i=1;i<=n;i++)
 81         printf("%d\n",result[i]);
 82 
 83     return 0;
 84 }
 85 /*
 86 5
 87 1 2 3 4 5
 88 1 2
 89 2 3
 90 3 4
 91 4 5
 92 
 93 
 94 5
 95 5 4 3 2 1
 96 1 2
 97 2 3
 98 3 4
 99 4 5
100 
101 1
102 1
103 
104 5
105 10 10 10 10 10
106 1 2
107 2 3
108 3 4
109 4 5
110 
111 
112 7
113 7 9 9 11 11 10 10
114 1 2
115 2 3
116 3 4
117 4 5
118 5 6
119 6 7
120 
121 */

/*1 製造比較小的隨機資料10以內的2 然後用std程式跑結果*/
#include <cstdio>#include <cstdlib>#include <cstring>#include <cmath>#include <cstdbool>#include <string>#include <algorithm>#include <iostream>#include <sstream>#include <ctime>#include <stack>#include <vector>#include <queue>#include <set>#include <map>using namespace std;
const double eps_1=1e-5;const double eps_2=1e-10;
const int maxn=5e5+10;



int l[maxn],r[maxn],v[maxn],result[maxn];int ql[maxn],qr[maxn],range[maxn];
int main(){ int inf=1e9+10; int n,i,j,k,o,ll=-inf,rr=inf,cnt=1,temp; range[0]=0; scanf("%d",&n); for (i=1;i<=n;i++) { scanf("%d%d",&l[i],&r[i]);
if (r[i]<ll || l[i]>rr) { range[cnt]=i-1; ql[cnt]=ll; qr[cnt]=rr;
ll=l[i]; rr=r[i]; cnt++; }
ll=max(ll, l[i]); rr=min(rr, r[i]); }
ql[cnt]=ll; qr[cnt]=rr; range[cnt]=n;



for (i=1;i<=cnt;i++) v[i]=ql[i];
if (cnt!=1) {
i=1; while (i<cnt) { if (i<cnt && ql[i]>ql[i+1]) { while (ql[i]>ql[i+1]) i++; if (i!=cnt) v[i]=qr[i]; } i++; }
if (ql[1]<ql[2]) v[1]=qr[1];
if (ql[cnt-1]>ql[cnt]) v[cnt]=qr[cnt]; }

for (i=1 ;i<=cnt;i++) { if (i!=1 && v[i]>v[i-1]) { temp = l[ range[i-1]+1 ]; for (o=range[i-1]+1 ; o<=range[i] ; o++) { if (l[o]>temp) temp=l[o]; if (temp==v[i]) break; result[o]=temp; } } else o=range[i-1]+1;
if (i!=cnt && v[i]>v[i+1]) { temp = v[i+1]; for (k=range[i] ; k>=o ; k--) { if (l[k]>temp) temp=l[k]; if (temp==v[i]) break; result[k]=temp; } } else k=range[i];
for (j=o ; j<=k ; j++) result[j]=v[i];
}
for (i=1;i<=n;i++) { printf("%d",result[i]); if (i!=n) printf(" "); }
return 0;}/*155 299 2815 194 267 2310 1312 253 116 171 2124 272 814 1820 2216 30


15 15 15 12 12 12 12 11 11 11 24 8 14 20 20




550 6040 5030 4020 3010 20
510 2020 3030 4040 5050 60
210 3040 60
240 6010 30
5100 200300 400500 60050 7020 40
*/

相關文章