Codeforces Round #252 (Div. 2)

A. Valera and Antique Items

题目大意:有一场拍卖,有n个卖家,每个卖家有ki个物品并且底价知道,你想买东西并且只有V元钱,问可以从哪几个商家那里去买

思路:对每个卖家的每样商品作比较即可

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #define maxn 1000
 5 using namespace std;
 6 int ans[maxn],h,x,k;
 7 int main()
 8 {
 9     int n,v;
10     scanf("%d%d",&n,&v);
11     for(int i=1;i<=n;i++)
12     {
13         scanf("%d",&k);
14         int flag=0;
15         for(int j=1;j<=k;j++)
16         {
17             scanf("%d",&x);
18             if(x<v && flag==0)ans[++h]=i,flag=1;
19         }
20     }
21     printf("%d\n",h);
22     for(int i=1;i<=h;i++)printf("%d ",ans[i]);
23     return 0;
24 }

B. Valera and Fruits

题目大意:你有n棵果树,每颗果树只能在ai ,a(i+1)两天时间内进行采摘,并且有bi个果子,你每天只能摘v个果子,问最多能摘多少果子?

思路:记录下每天有多少果子,显然在还能摘的前提下先摘昨天的最优,然后贪心即可

 1 #include<cstdio>
 2 #include<algorithm>
 3 #define maxn 10000
 4 using namespace std;
 5 struct T
 6 {
 7     int x;int y;
 8 }a[maxn];
 9 int cmp(T a ,T b)
10 {
11     return a.x<b.x;
12 }
13 int day[maxn];
14 int main()
15 {
16     int n,v;
17     scanf("%d%d",&n,&v);
18     for(int i=1;i<=n;i++)
19     {
20         scanf("%d%d",&a[i].x,&a[i].y);
21         day[a[i].x]+=a[i].y;
22     }
23     int ans=0;
24     for(int i=1;i<=3009;i++)
25     {
26         if(v<=day[i-1])
27         {
28             ans+=v;
29         }
30         else
31         {
32             ans+=day[i-1];
33             int u=v-day[i-1];
34             if(day[i]>=u)
35             {
36                 day[i]-=u;
37                 ans+=u;
38             }
39             else
40             {
41                 ans+=day[i];
42                 day[i]=0;
43             }
44         }
45     }
46     printf("%d\n",ans);
47     return 0;
48 }

C. Valera and Tubes

题目大意:你有一个N*M的棋盘放管子,每个管子至少覆盖两个ceil,要你给出一个不重不漏的覆盖满整个棋盘并且恰好只有k个管子的方案

思路:我先蛇形的放一个长长的管子,然后进行分割每次分割一个长度为2的管子即可

 1 #include<cstdio>
 2 #include<iostream>
 3 using namespace std;
 4 int dir=1,x=1,y=0,n,m,r;
 5 int next()
 6 {
 7     if(dir==1)
 8     {
 9         if(y==m)x++,dir--;else
10         y++;
11     }
12     else
13     {
14         if(y==1)x++,dir++;else y--;
15     }
16     printf("%d %d ",x,y);
17 }
18 int main()
19 {
20     scanf("%d%d%d",&n,&m,&r);
21     for(int i=1;i<r;i++)
22     {
23         printf("2 ");next();next();
24         puts("");
25     }
26     printf("%d ",n*m-(r-1)*2);
27     for(int i=1;i<=n*m-(r-1)*2;i++)next();
28     return 0;
29 }

D. Valera and Swaps

题目大意:你有一个n个元素的排列p,定义f(p)是最少的使p变成 1 2 3 4  5....形式排列的交换次数,给你一个数字k,要你给出最少的交换方案,使得p变成q并且f(q)=k,多个方案满足时用交换方案字典序最小的

思路:有了思维定势:只能交换相邻元素的排列要逆序数上想,能交换任意两个元素的要往置换群上想,然后置换群显然需要分解成n个轮换的乘积,一个k轮换显然需要交换k-1次才能归位,然后发现假设能分解成m个轮换,那需要交换的次数为n-m,交换一个轮换内的元素会使轮换个数+1,交换不同轮换内的元素会使轮换个数-1,想到了这些便可以瞎搞了

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #define maxn 10000
 5 using namespace std;
 6 int visit[maxn],p[maxn],kk;
 7 int dfs(int k,int ini)
 8 {
 9     if(k!=ini && k-ini<=kk-ini)kk=k;
10     if(visit[k]==1)return k-1;
11     visit[k]=1;
12     return dfs(p[k],ini);
13 }
14 int main()
15 {
16     int n,ans=0,k;
17     scanf("%d",&n);
18     for(int i=1;i<=n;i++)
19     {
20         scanf("%d",&p[i]);
21     }
22     scanf("%d",&k);
23     int cir=0;
24     for(int i=1;i<=n;i++)
25     {
26         if(!visit[i])dfs(i,i),cir++;
27     }
28     if(n-cir==k)
29     {
30         puts("0");
31     }
32     else if(n-cir<k)//add repeted
33     {
34         printf("%d\n",k-n+cir);
35         for(int i=1;i<=k-n+cir;i++)
36         {
37             memset(visit,0,sizeof(visit));
38             dfs(1,1);
39             int j;
40             for(j=1;j<=n;j++)
41             {
42                 if(!visit[j])break;
43             }
44             swap(p[1],p[j]);
45             printf("1 %d ",j);
46         }
47     }
48     else
49     {
50         printf("%d\n",n-k-cir);
51         for(int i=1;i<=n-k-cir;i++)
52         {
53             memset(visit,0,sizeof(visit));
54             int ans=0,j;
55             for(j=1;j<=n;j++)
56             {
57                 kk=0x3f3f3f3f;
58                 if(p[j]!=j)
59                 {
60                     int kk=0x3f3f3f3f;
61                     dfs(j,j);
62                     break;
63                 }
64             }
65             swap(p[j],p[kk]);
66             printf("%d %d ",j,kk);
67         }
68     }
69     return 0;
70 }

时间: 2024-11-06 07:28:30

Codeforces Round #252 (Div. 2)的相关文章

Codeforces Round #252 (Div. 2) A - Valera and Antique Items

水题 #include <iostream> #include <set> #include <vector> #include <algorithm> using namespace std; int main(){ int n,v; cin >> n >> v; vector<int> res; for(int i = 0; i < n; ++ i){ int k,s; bool flag = false; ci

CodeForces 441E(Codeforces Round #252 (Div. 2))

思路:dp[i][now][mark][len]   i 表示当前第i 次now存的是后8位,mark为第9位为0还是1 len第九位往高位还有几位和第9位相等.  只存后8位的原因:操作只有200次每次都为加法的话后8位可以表示,如果为乘法第八位已知再加上第九位 和往前的长度已知,所以可以表示所有状态. 所存在问题就是 10 1111 1111 此时加上1之后 会变成 11 0000 0000 但这样并处影响结果 如果之后操作都为加法,只有200次,他不可能影响到前面的1, 乘法相当于左移也不

Codeforces Round #252 (Div. 2)-C,D

C题就是一个简单的模拟,首先给每个人两个.然后把剩下的都给一个人就好了. 给的时候蛇形给. #include<stdio.h> #include<string.h> #include<algorithm> #include<iostream> #include<vector> #include<queue> using namespace std; #define LL __int64 #define maxn 330000 int

codeforces Round #252 (Div. 2) C - Valera and Tubes

贪心算法,每条路径最短2格,故前k-1步每次走2格,最后一步全走完 由于数据比较小,可以先打表 #include <iostream> #include <vector> #include <algorithm> #include <utility> using namespace std; typedef pair<int,int> Point; int main(){ int n, m, k, flag = -1; cin >>

Codeforces Round #279 (Div. 2) ABCD

Codeforces Round #279 (Div. 2) 做得我都变绿了! Problems # Name     A Team Olympiad standard input/output 1 s, 256 MB  x2377 B Queue standard input/output 2 s, 256 MB  x1250 C Hacking Cypher standard input/output 1 s, 256 MB  x740 D Chocolate standard input/

Codeforces Round #428 (Div. 2)

Codeforces Round #428 (Div. 2) A    看懂题目意思就知道做了 #include<bits/stdc++.h> using namespace std; #pragma comment(linker, "/STACK:102400000,102400000") #define rep(i,a,b) for (int i=a; i<=b; ++i) #define per(i,b,a) for (int i=b; i>=a; --i

Codeforces Round #424 (Div. 2) D. Office Keys(dp)

题目链接:Codeforces Round #424 (Div. 2) D. Office Keys 题意: 在一条轴上有n个人,和m个钥匙,门在s位置. 现在每个人走单位距离需要单位时间. 每个钥匙只能被一个人拿. 求全部的人拿到钥匙并且走到门的最短时间. 题解: 显然没有交叉的情况,因为如果交叉的话可能不是最优解. 然后考虑dp[i][j]表示第i个人拿了第j把钥匙,然后 dp[i][j]=max(val(i,j),min(dp[i-1][i-1~j]))   val(i,j)表示第i个人拿

Codeforces Round #424 (Div. 2) C. Jury Marks(乱搞)

题目链接:Codeforces Round #424 (Div. 2) C. Jury Marks 题意: 给你一个有n个数序列,现在让你确定一个x,使得x通过挨着加这个序列的每一个数能出现所有给出的k个数. 问合法的x有多少个.题目保证这k个数完全不同. 题解: 显然,要将这n个数求一下前缀和,并且排一下序,这样,能出现的数就可以表示为x+a,x+b,x+c了. 这里 x+a,x+b,x+c是递增的.这里我把这个序列叫做A序列 然后对于给出的k个数,我们也排一下序,这里我把它叫做B序列,如果我

[Codeforces] Round #352 (Div. 2)

人生不止眼前的狗血,还有远方的狗带 A题B题一如既往的丝帛题 A题题意:询问按照12345678910111213...的顺序排列下去第n(n<=10^3)个数是多少 题解:打表,输出 1 #include<bits/stdc++.h> 2 using namespace std; 3 int dig[10],A[1005]; 4 int main(){ 5 int aa=0; 6 for(int i=1;;i++){ 7 int x=i,dd=0; 8 while(x)dig[++dd