第十九周 1.4---1.10

文章包含了一系列编程挑战的解决策略,涉及数据结构、算法优化、软件工程实践等关键主题,旨在提升读者的编程技能和解决问题的能力。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

终于考完了

----

诶--- --- ---

1.7

cf500c

http://codeforces.com/problemset/problem/500/C

补去年的题了......(不,,,是前年---呜呜呜--)

懒成狗了......

给出 n 本书的重量,m 天,还有这m 天每天要看哪一本书,然后每次看一本书的时候,是将这本书上面的书拿走,再拿走要看的书,再把挪走的那一摞书放回来

确定书最开始的顺序,使得搬的书的重量最小

按照看书的先后顺序来放,没有出现过的书就不管

假设现在要看的书是 x ,它的上面有 m 这么重的书

现在需要搬 m

如果不是按照看书的顺序来放的放,假设现在有一个m0在x 的上面

现在需要搬动 m + m0 > m

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<algorithm>
 5 using namespace std;
 6 
 7 const int maxn = 1005;
 8 int a[maxn],w[maxn];
 9 int n,m;
10 int b[maxn],vis[maxn];
11 int c[maxn];
12 
13 void solve(){
14     int cnt = 0;
15     memset(vis,0,sizeof(vis));
16     memset(c,0,sizeof(c));
17     for(int i = 1;i <= m;i++){
18         if(!vis[a[i]]){
19             b[++cnt] = a[i];
20             vis[a[i]] = 1;
21         }
22     }
23 
24   /*  for(int i = 1;i <= cnt;i++){
25         printf("b[%d] = %d\n",i,b[i]);
26     }*/
27 
28     int ans = 0;
29     for(int i = 1;i <= m;i++){
30         int pos = 0;
31         for(int j = 1;j <= cnt;j++){
32             if(b[j] == a[i]) {
33                 pos = j;
34                 break;
35             }
36             ans += w[b[j]];
37           //  printf("--- i = %d  b[%d] = %d\n",i,j,b[j]);
38         }
39         memcpy(c,b,sizeof(b));
40         for(int j = 1;j < pos;j++){
41             b[j+1] = c[j];
42         }
43         b[1] = a[i];
44 
45        /* for(int j = 1;j <= cnt;j++){
46             printf("  %d  ",b[j]);
47         }
48         printf("\n");*/
49     }
50     printf("%d\n",ans);
51 }
52 
53 int main(){
54     while(scanf("%d %d",&n,&m) != EOF){
55         for(int i = 1;i <= n;i++) scanf("%d",&w[i]);
56         for(int i = 1;i <= m;i++) scanf("%d",&a[i]);
57         solve();
58     }
59     return 0;
60 }
View Code

 

1.8

...今天做了一件sb的事情

是这样的--

cf 609e

http://codeforces.com/contest/609/problem/E

给出 n 个点,m条边的一个图,然后求使得mi 在最小生成树里面的时候 的 mst

先求出原图的mst

如果这条边在最小生成树上,就直接输出 mst

如果不在,就求出 lca(u,v),查询 u 到 lca , v 到 lca 的路径上的权值最大的一条边

(本来,,本来,求Lca的时候,就可以把这个最大值求出来的---,,,sb地以为要用树剖---

抄板抄了一下午,,,代码写了200多行---蠢哭了......),

再把这条边替换成mi就可以了---

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<cmath>
  4 #include<vector>
  5 #include<map>
  6 #include<set>
  7 #include<queue>
  8 #include<iostream>
  9 #include<algorithm>
 10 using namespace std;
 11 #define lp (p << 1)
 12 #define rp (p << 1 | 1)
 13 #define getmid(l,r) (l+(r-l)/2)
 14 typedef long long ll;
 15 const int INF = 1 << 30;
 16 const int maxn = 4e5+5;
 17 const int MAX_LOG = 32;
 18 
 19 int T,N,M;
 20 int dep[maxn],sz[maxn],son[maxn],fa[MAX_LOG][maxn];
 21 int top[maxn],tsz,w[maxn],tmax[maxn<<2];
 22 int first[maxn];
 23 int ecnt;
 24 int e[maxn][5];
 25 
 26 struct Edge{
 27     int u,v,w;
 28     int nxt;
 29     int tag;
 30     int id;
 31 }ee[maxn*2];
 32 
 33 int cmp(Edge n1,Edge n2){
 34     return n1.w < n2.w;
 35 }
 36 
 37 int cmp0(Edge n1,Edge n2){
 38     return n1.id < n2.id;
 39 }
 40 
 41 Edge edge[maxn*2];
 42 int pp[maxn];
 43 
 44 void Add_edge(int u,int v,int w){
 45     ee[++ecnt].nxt = first[u];
 46     ee[ecnt].v = v;
 47     ee[ecnt].u = u;
 48     ee[ecnt].w = w;
 49     first[u] = ecnt;
 50 }
 51 
 52 int findfa(int x){
 53     return x == pp[x] ? x :pp[x] = findfa(pp[x]);
 54 }
 55 
 56 void Dfs(int p){
 57    // printf("p = %d\n",p);
 58     sz[p] = 1;
 59     son[p] = -1;
 60     int maxx = 0;
 61     int v;
 62     for(int i = first[p];~i;i = ee[i].nxt){
 63          v = ee[i].v;
 64         if(v == fa[0][p]) continue;
 65         dep[v] = dep[p] + 1;
 66         fa[0][v] = p;
 67         Dfs(v);
 68         if(sz[v] > maxx){
 69             son[p] = v;
 70             maxx = sz[v];
 71         }
 72     }
 73     sz[p] += sz[v];
 74 }
 75 
 76 void Build_tree(int p,int tp){
 77     w[p] = ++tsz;
 78     top[p] = tp;
 79     if(son[p] != -1) {
 80         Build_tree(son[p],tp);
 81     }
 82     for(int i = first[p];~i;i = ee[i].nxt){
 83         int v = ee[i].v;
 84         if(v != son[p] && v != fa[0][p]){
 85             Build_tree(v,v);
 86         }
 87     }
 88 }
 89 
 90 void Update_tree(int a,int v,int p,int l,int r){
 91     if(l == r){
 92         tmax[p] = v;
 93         return;
 94     }
 95     int mid = getmid(l,r);
 96     if(a <= mid) Update_tree(a,v,lp,l,mid);
 97     else Update_tree(a,v,rp,mid+1,r);
 98     tmax[p] = max(tmax[lp],tmax[rp]);
 99 }
100 
101 int Query_tree(int a,int b,int p,int l,int r){
102     if(a <= l && r <= b) return tmax[p];
103     int res = -INF;
104     int mid = getmid(l,r);
105     if(a <= mid) res = max(res,Query_tree(a,b,lp,l,mid));
106     if(b > mid) res = max(res,Query_tree(a,b,rp,mid+1,r));
107     return res;
108 }
109 
110 int Find(int a,int b){
111     int f1 = top[a],f2 = top[b];
112     int ans = 0;
113     while(f1 != f2){
114         if(dep[f1] > dep[f2]){
115             swap(a,b);
116             swap(f1,f2);
117         }
118         ans = max(ans,Query_tree(w[f2],w[b],1,1,tsz));
119         b = fa[0][f2];
120         f2 = top[b];
121     }
122     if(a == b) return ans;
123     if(dep[a] > dep[b]) swap(a,b);
124     return max(ans,Query_tree(w[son[a]],w[b],1,1,tsz));
125 }
126 
127 void Init(){
128     tsz = -1;
129     fa[0][1] = dep[1] = 0;
130     memset(sz,0,sizeof(sz));
131     memset(tmax,0,sizeof(tmax));
132     memset(first,-1,sizeof(first));
133     ecnt = 0;
134 }
135 
136 void Pre(){
137     for(int k = 0; k + 1 < MAX_LOG; ++k){
138         for(int v = 1; v <= N; ++v){
139             if(fa[k][v] < 0) fa[k + 1][v] = -1;
140             else fa[k + 1][v] = fa[k][fa[k][v]];
141         }
142     }
143 }
144 
145 int Lca(int u,int v){
146     if(dep[u] > dep[v]) swap(u,v);
147     for(int k = MAX_LOG - 1; k >= 0; --k){
148         if((dep[v] - dep[u]) & (1 << k))
149             v = fa[k][v];
150     }
151     if(u == v) return u; //u为v的根
152     for(int k = MAX_LOG - 1; k >= 0; --k){
153         if(fa[k][u] != fa[k][v]){
154             u = fa[k][u];
155             v = fa[k][v];
156         }
157     }
158     return fa[0][u]; //u离lca只差一步
159 }
160 
161 int main(){
162     char s[10];
163     int a,b,c;
164     while(scanf("%d %d",&N,&M) != EOF){
165         Init();
166         for(int i = 1;i <= M;i++){
167             scanf("%d %d %d",&edge[i].u,&edge[i].v,&edge[i].w);
168             edge[i].id = i;
169             edge[i].tag = 0;
170         }
171         for(int i = 1;i <= N;i++) pp[i] = i;
172         sort(edge+1,edge+M+1,cmp);
173         ll mst = 0;
174         for(int i = 1;i <= M;i++){
175             int u = edge[i].u;
176             int v = edge[i].v;
177             int x = findfa(u),y = findfa(v);
178             if(x != y){
179                 edge[i].tag = 1;
180                 mst += 1ll*edge[i].w;
181                 pp[x] = y;
182             }
183         }
184 
185        /* for(int i = 1;i <= M;i++){
186             printf("u = %d  v = %d  edge[%d].tag = %d\n",edge[i].u,edge[i].v,i,edge[i].tag);
187         }*/
188 
189         memset(e,0,sizeof(e));
190         int cnt = 0;
191         for(int i = 1;i <= M;i++){
192             if(edge[i].tag == 0) continue;
193             int a ,b,c;
194             a = edge[i].u;
195             b = edge[i].v;
196             c = edge[i].w;
197             e[++cnt][0] = a;
198             e[cnt][1] = b;
199             e[cnt][2] = c;
200             Add_edge(a,b,c);
201             Add_edge(b,a,c);
202         }
203 
204         Dfs(1);
205         Build_tree(1,1);
206         for(int i = 1;i < N;i++){
207             if(dep[e[i][0]] > dep[e[i][1]]) swap(e[i][0],e[i][1]);
208             Update_tree(w[e[i][1]],e[i][2],1,1,tsz);
209         }
210       /*  for(int i = 1;i <= ecnt;i++){
211             printf("ee[%d].u = %d  v = %d\n",i,ee[i].u,ee[i].v);
212         }
213 
214       /*  for(int i = 1;i <= 5;i++){
215             int u,v;
216             scanf("%d %d",&u,&v);
217             printf("---%d\n",Find(u,v));
218         }*/
219 
220         sort(edge+1,edge+M+1,cmp0);
221         Pre();
222         for(int i = 1;i <= M;i++){
223          //   printf("edge[%d].u = %d  v = %d\n",i,edge[i].u,edge[i].v);
224             if(edge[i].tag == 1){
225                 printf("%I64d\n",mst);
226                 continue;
227             }
228             int u = edge[i].u;
229             int v = edge[i].v;
230             int lca = Lca(u,v);
231             int maxx = 0;
232             maxx = max(maxx,Find(u,lca));
233             maxx = max(maxx,Find(v,lca));
234             ll res = 0;
235             res = mst - maxx + 1ll*edge[i].w;
236             printf("%I64d\n",res);
237            // printf("u = %d  v = %d  lca = %d\n",u,v,lca);
238         }
239     }
240     return 0;
241 }
View Code

 

1.9

滚回家

话说还以为一年没回家,,汽车站修成新的了,,后来才发现自己sb地坐过站了(压根不是一个地方嘛------)- -

 

1.10

cf 609d

http://codeforces.com/contest/609/problem/D

题意好绕阿

给出 n 天,m个物品,需要买k件物品,s 个burle ,每个物品对应有一个type 还有一个 c (汇率)

type 为 1 的物品只能够用美元来购买

type 为 2的物品只能够用英镑来购买

再分别给出这n天 的美元,英镑 对 burle 的汇率

问买够这k件物品至少需要花多少天,输出天数,再分别输出这k件物品分别是哪一天购买的

二分天数x,再贪心地求出 在这 x 天里面,对应的哪一天美元,英镑的汇率最低,

再用这个来算购买每个物品需要花的钱,升序排序,贪心买k个,看花的钱是不是<= s

 

----

本来这样是 t 了的,,于是跑去预处理了下那个汇率

还是 t 了---

后来发现二分50次的话,不用预处理汇率也可以---唉---

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<cmath>
  4 #include<iostream>
  5 #include<algorithm>
  6 using namespace std;
  7 
  8 typedef long long ll;
  9 const int maxn = 4e5+5;
 10 int a[maxn],b[maxn];
 11 int n,m,k,s;
 12 
 13 struct node{
 14     int t,c;
 15     ll w;
 16     int id;
 17     int tag;
 18 };
 19 
 20 node p[maxn];
 21 
 22 int cmp(node n1,node n2){
 23     return n1.w < n2.w;
 24 }
 25 
 26 int cmp0(node n1,node n2){
 27     return n1.id < n2.id;
 28 }
 29 
 30 int ixd,ixp;
 31 int pred[maxn][2];
 32 int prep[maxn][2];
 33 
 34 int ok(int x){
 35     int md = pred[x][0];
 36     int mp = prep[x][0];
 37     ixd = pred[x][1];
 38     ixp = prep[x][1];
 39 
 40     for(int i = 1;i <= m;i++){
 41         if(p[i].t == 1) p[i].w = 1ll*md*p[i].c;
 42         else p[i].w = 1ll*mp*p[i].c;
 43     }
 44     sort(p+1,p+m+1,cmp);
 45     ll res = 0;
 46     for(int i = 1;i <= k;i++){
 47         res += 1ll*p[i].w;
 48     }
 49     //printf("x = %d  res = %I64d  md = %d  mp = %d\n",x,res,md,mp);
 50     return res <= s;
 51 }
 52 
 53 void solve(){
 54     pred[1][0] = a[1];
 55     pred[1][1] = 1;
 56     prep[1][0] = b[1];
 57     prep[1][1] = 1;
 58 
 59     for(int i = 2;i <= n;i++){
 60         if(a[i] < pred[i-1][0]){
 61             pred[i][0] = a[i];
 62             pred[i][1] = i;
 63         }
 64         else{
 65             pred[i][0] = pred[i-1][0];
 66             pred[i][1] = pred[i-1][1];
 67         }
 68 
 69         if(b[i] < prep[i-1][0]){
 70             prep[i][0] = b[i];
 71             prep[i][1] = i;
 72         }
 73         else{
 74             prep[i][0] = prep[i-1][0];
 75             prep[i][1] = prep[i-1][1];
 76         }
 77     }
 78 
 79     int lb = 1,ub = n,mid;
 80     int ans = 1e9+7;
 81     int flag = 0;
 82     for(int i = 0;i <= 50;i++){
 83         mid = (lb+ub)/2;
 84         if(ok(mid)) {
 85             ans = min(ans,mid);
 86             ub = mid;
 87             flag = 1;
 88         }
 89         else lb = mid+1;
 90       //  printf("mid = %d  lb = %d ub = %d\n",mid,lb,ub);
 91     }
 92     if(!flag) puts("-1");
 93     else{
 94         printf("%d\n",ans);
 95         for(int i = 1;i <= m;i++){
 96             if(i <= k) p[i].tag = 1;
 97             else p[i].tag = 0;
 98         }
 99         sort(p+1,p+m+1,cmp0);
100         for(int i = 1;i <= m;i++){
101             if(p[i].tag == 0) continue;
102             if(p[i].t == 1){
103                 printf("%d %d\n",p[i].id,ixd);
104             }
105             else{
106                 printf("%d %d\n",p[i].id,ixp);
107             }
108         }
109     }
110 }
111 
112 int main(){
113     while(scanf("%d %d %d %d",&n,&m,&k,&s) != EOF){
114         for(int i = 1;i <= n;i++) scanf("%d",&a[i]);
115         for(int i = 1;i <= n;i++) scanf("%d",&b[i]);
116         for(int i = 1;i <= m;i++){
117             scanf("%d %d",&p[i].t,&p[i].c);
118             p[i].id = i;
119         }
120         solve();
121     }
122     return 0;
123 }
View Code

 

cf 608b

http://codeforces.com/contest/608/problem/B

很水很水的一道题了叭,,可是当时就是不会做,好笨阿

给出 a 串 和 b 串

定义 距离 为 d = b[i] - a[i];

求所有的 b 的长度 为 a 的子串的 d 之和

对应 a 串中的每一个字符,它在 b 串中有连续的一段区间

这段区间 为 [i,lenb-lena+i] (当时死活想不出这个区间是啥,,觉得边界会很麻烦,,可是就是是这样子了---唉--)

然后再算出 b 串 的前缀 0 的个数,前缀 1 的个数

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<algorithm>
 5 using namespace std;
 6 
 7 typedef long long LL;
 8 const int maxn = 2e5+5;
 9 int ling[maxn],yi[maxn];
10 char a[maxn],b[maxn];
11 
12 void solve(){
13     int lena = strlen(a+1);
14     int lenb = strlen(b+1);
15     memset(ling,0,sizeof(ling));
16     memset(yi,0,sizeof(yi));
17     for(int i = 1;i <= lenb;i++){
18         if(b[i] == '0') ling[i] = ling[i-1]+1;
19         else ling[i] = ling[i-1];
20 
21         if(b[i] == '1') yi[i] = yi[i-1]+1;
22         else yi[i] = yi[i-1];
23     }
24 
25     /*for(int i = 1;i <= lenb;i++){
26         printf("ling[%d] = %d\n",i,ling[i]);
27         printf("yi[%d] = %d\n",i,yi[i]);
28     }*/
29 
30     int ed = lenb-lena;
31     LL ans = 0;
32     LL tmp = 0;
33     for(int i = 1;i <= lena;i++){
34         if(a[i] == '0'){
35             tmp = 1LL*(yi[ed+i]-yi[i-1]);
36         }
37         else {
38             tmp = 1LL*(ling[ed+i]-ling[i-1]);
39         }
40         ans += 1LL*tmp;
41        // printf("tmp = %I64d\n",tmp);
42     }
43     printf("%I64d\n",ans);
44 }
45 
46 int main(){
47     scanf("%s",a+1);
48     scanf("%s",b+1);
49     solve();
50 }
View Code

 

转载于:https://www.cnblogs.com/wuyuewoniu/p/5111663.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值