*Codeforces Round #251 (Div. 2)AK)

A、确定性数学计算,水,读题要快

 1 #include<iostream>
2 #include<stdio.h>
3
4 using namespace std;
5 int N,d;
6 int main(){
7 while(~scanf("%d%d",&N,&d)){
8 int cnt=0;
9 for(int i=0;i<N;i++){
10 int t;
11 scanf("%d",&t);
12 cnt+=t;
13 }
14 if (cnt+(N-1)*10>d){
15 printf("-1\n");continue;
16 }
17 int ans=(N-1)*10/5+(d-(cnt+(N-1)*10))/5;
18 cout<<ans<<endl;
19
20 }
21 return 0;
22 }

B、贪心,章节少的课先学,排序+贪心+long long 处理细节

 1 #include<iostream>
2 #include<stdio.h>
3 #include<algorithm>
4 #include<stdlib.h>
5
6 using namespace std;
7 int n,s;
8 int a[100005];
9
10 int main(){
11 while(~scanf("%d%d",&n,&s)){
12 for(int i=0;i<n;i++) scanf("%d",&a[i]);
13 sort(a,a+n);
14 long long ans=0;
15 s++;
16 for(int i=0;i<n;i++){
17 if (s>1) s--;
18 ans+=(long long)s*a[i];//在s前面加了long long 就过了,伤不起,应该是要强制转化成long long,不然后面两个int计算只保留了int部分
19 }
20 cout<<ans<<endl;
21 }
22 return 0;
23 }

注意:ans+=(long long)s*a[i];//在s前面加了long long 就过了,伤不起,应该是要强制转化成long
long,不然后面两个int计算只保留了int部分

C、确定性数学证明(奇偶证明)+策略模拟 (很容易粗)

我的写法还是不是很好,下标算来算去,这道题一定要考虑到p-k==0的情况,不然会出错,

给自己出数据的时候,没有考虑到这个情况,比赛的时候可能就会跪了

 1 #include <iostream>
2 #include <stdio.h>
3 #include <string.h>
4 using namespace std;
5 int n,k,p,d;//p个偶数组合
6 int a[100006],b[100006];
7 int main()
8 {
9 while(~scanf("%d%d%d",&n,&k,&p)){
10 int cnt1=0,cnt2=0;
11 for(int i=0;i<n;i++){
12 int num;
13 scanf("%d",&num);
14 if (num % 2 == 0) a[cnt1++]=num;else b[cnt2++]=num;
15 }
16 int p1=p,p2=k-p;
17 if (cnt1+cnt2/2<p1){
18 cout<<"NO"<<endl;
19 continue;
20 }
21 if (cnt1>=p1){
22 if (cnt2<p2 || cnt2 % 2 != p2 % 2){
23 cout<<"NO"<<endl;
24 continue;
25 }
26 cout<<"YES"<<endl;
27 if (p2>0){
28 for(int i=0;i<p1;i++){
29 cout<<1<<" "<<a[i]<<endl;
30 }
31 cnt1=cnt1-p1;
32 cout<<cnt1+(cnt2-p2)+1<<" ";
33 for(int i=p1;i<p1+cnt1;i++){
34 cout<<a[i]<<" ";
35 }
36 for(int i=0;i<(cnt2-p2)+1;i++){
37 if (i==cnt2-p2){
38 cout<<b[i]<<endl;
39 }else cout<<b[i]<<" ";
40 }
41 for(int i=cnt2-p2+1;i<cnt2;i++){
42 cout<<1<<" "<<b[i]<<endl;
43 }
44 }else{
45 cout<<cnt1-p1+1+cnt2;
46 for(int i=0;i<cnt1-p1+1;i++) cout<<" "<<a[i];
47 for(int i=0;i<cnt2;i++) cout<<" "<<b[i];
48 cout<<endl;
49 for(int i=cnt1-p1+1;i<cnt1;i++){
50 cout<<1<<" "<<a[i]<<endl;
51 }
52 }
53
54 continue;
55 }else {
56 if (cnt2-(p1-cnt1)*2<p2 || (cnt2-(p1-cnt1)*2) % 2 != p2 %2 ){
57 cout<<"NO"<<endl;
58 continue;
59 }
60 cout<<"YES"<<endl;
61 for(int i=0;i<cnt1;i++){
62 cout<<1<<" "<<a[i]<<endl;
63 }
64
65 d=0;
66 if (p2>0){//这里是个大坑
67 for(int i=cnt1;i<p1;i++){
68 cout<<2<<" "<<b[d++]<<" "<<b[d++]<<endl;
69 }
70 }else {//p2==0
71 for(int i=cnt1;i<p1-1;i++){
72 cout<<2<<" "<<b[d++]<<" "<<b[d++]<<endl;
73 }
74 cout<<cnt2-d<<" ";
75 for(int i=d;i<cnt2;i++){
76 if (i==cnt2-1) cout<<b[i]<<endl;else cout<<b[i]<<" ";
77 d++;
78 }
79 }
80 if (cnt2==d) continue;
81 if (cnt2 - d > p2){
82
83 cout<<cnt2-d-p2+1<<" ";
84 for(int i=d;i<cnt2-p2+1;i++){
85 if (i==cnt2-p2){
86 cout<<b[i]<<endl;
87 }else {
88 cout<<b[i]<<" ";
89 }
90 }
91 for(int i=cnt2-p2+1;i<cnt2;i++) cout<<1<<" "<<b[i]<<endl;
92 }else {//cnt2-d==p2
93 for(int i=d;i<cnt2;i++) cout<<1<<" "<<b[i]<<endl;
94 }
95 }
96 }
97 return 0;
98
99 }

 D、三分搜索+贪心+枚举(也可以排序+二分搜索(优化1/2的常数))

题目描述:给定A数组,n个数,给定B数组,m个数,

定义操作:一次任选数组,任选一个元素,可以增大或减少;

求一个最小操作数,使得改变后,A中最小的元素a大于等于B中最大的元素b。

方法就是上面所说的:

1、三分F(X):假设最终a=b=x,注意a和b肯定相等,因为我们是向中间取数的。不等没有相等步数少。

这样能确定x的范围,min(A)到max(B),因为我们肯定是增大A中元素,减小B中元素。

但是我不能证明是凹性的函数啊!!!

2、选定x,贪心的策略就定下来了:

if (a[i]<x) ans+=x-a[i];//尽可能用最小的步数达成目的

3、三分写法再总结:

(1)用t控制次数,不写while

(2)最终在[l,r]的范围内找到极值

(3)注意画图,尽可能地包含极值点

下面是别人的证明:

 1 #include<iostream>
2 #include<stdio.h>
3 #include<algorithm>
4 #include<stdlib.h>
5 #define LL long long
6 using namespace std;
7 int n,m;
8 LL a[100005],b[100005];
9 LL F(LL x)
10 {
11 //将A数组中的变成至少为x;(增加)
12 LL ans=0;
13 for(int i=0; i<n; i++) //可二分优化
14 {
15 if (a[i]<x) ans+=x-a[i];
16 }
17 //将A数组中的变成最多为x;(减少)
18 for(int i=0; i<m; i++)
19 {
20 if (b[i]>x) ans+=b[i]-x;
21 }
22 return ans;
23 }
24 int main()
25 {
26 // freopen("out.txt","w",stdout);
27 while(~scanf("%d%d",&n,&m))
28 {
29 LL Min=1e12,Max=-1;
30 for(int i=0; i<n; i++)
31 {
32 scanf("%I64d",&a[i]);
33 Min=min(Min,a[i]);
34 }
35 for(int i=0; i<m; i++)
36 {
37 scanf("%I64d",&b[i]);
38 Max=max(Max,b[i]);
39 }
40 sort(a,a+n);
41 sort(b,b+m);
42 LL l=Min-1,r=Max+1;
43 for(int i=0; i<100; i++)
44 {
45 int m1=l+(r-l)/3,m2=r-(r-l)/3;
46 if (F(m1)<F(m2)) r=m2;
47 else l=m1;
48 }
49 LL ans=F(l);
50 for(LL i=l;i<=r;i++) ans=min(ans,F(i));
51 cout<<ans<<endl;
52 }
53 return 0;
54 }

E、dp(关键是记忆化的思想)+乘法逆(数学考得好啊)

ps:题解:http://codeforces.com/blog/praveen123

推导过程太精妙了

暂时超时的代码:

 1 #include <iostream>
2 #include <string.h>
3 #include <stdio.h>
4 #define LL long long
5 #define Mod 1000000007
6 LL d[100005];
7 LL Jie[100005];
8 using namespace std;
9 void gcd(LL a,LL b,LL& d,LL& x,LL& y){
10 if (!b){d=a;x=1;y=0;}
11 else {gcd(b,a%b,d,y,x);y-=x*(a/b);}
12 }
13 LL inv(LL a,LL n){
14 LL d,x,y;
15 gcd(a,n,d,x,y);
16 return d==1?(x+n)%n:-1;
17 }
18 void init(){//生成C[x,f]的数表,n是最大范围
19 Jie[0]=1;
20 for(int i=1;i<=100005;i++)
21 Jie[i]=(Jie[i-1]*i)%Mod;
22 }
23 LL calC(int n,int r){
24 LL ans=Jie[n];
25 LL k=Jie[r] * Jie[n-r];k=k%Mod;
26 return (ans * inv(k,Mod)) % Mod;
27 }
28 LL dp(int n,int f){
29 // cout<<"n="<<n<<","<<"f="<<f<<endl;
30 if (n<f) return 0;
31 if (n==f) return 1;
32 if (d[n]!=-1) return d[n];
33 LL ans=calC(n-1,f-1);//得到C(n-1,f-1) //隔板法
34 LL sum=0;
35 for(int i=2;i<=n;i++){
36 if (n % i == 0) sum+=dp(n/i,f);
37 sum=sum % Mod;
38 }
39 ans=(ans-sum + Mod) % Mod;
40 return d[n]=ans;
41 }
42 int main(){
43 init();
44 int n,f,t;
45 scanf("%d",&t);
46 while(~scanf("%d%d",&n,&f)){
47 if (n<f){
48 cout<<0<<endl;
49 continue;
50 }
51 memset(d,-1,sizeof(d));
52 LL ans=dp(n,f);
53 cout<<ans<<endl;
54 }
55 return 0;
56 }

*Codeforces Round #251 (Div. 2)AK),布布扣,bubuko.com

时间: 2024-12-17 20:21:39

*Codeforces Round #251 (Div. 2)AK)的相关文章

Codeforces Round #251 (Div. 2) C. Devu and Partitioning of the Array

注意p的边界情况,p为0,或者 p为k 奇数+偶数 = 奇数 奇数+奇数 = 偶数 #include <iostream> #include <vector> #include <set> #include <algorithm> #include <cmath> using namespace std; int main(){ int n,k,p; long a; cin >> n >> k >> p; ve

Codeforces Round #251 (Div. 2) B. Devu, the Dumb Guy

注意数据范围即可 #include <iostream> #include <vector> #include <algorithm> using namespace std; int main(){ long long n,x; cin >> n >> x; vector<long long> c(n); for(int i = 0 ; i < n; ++ i) cin >> c[i]; sort(c.begin(

Codeforces Round #251 (Div. 2) A - Devu, the Singer and Churu, the Joker

水题 #include <iostream> #include <vector> #include <algorithm> using namespace std; int main(){ int n,d,t; cin >> n >> d; for(int i = 0 ; i < n; ++ i){ cin >> t; d-=t; } d-=(n-1)*10; if(d < 0) cout<<-1<<

Codeforces Round #251 (Div. 2) C、D

Codeforces Round #251 (Div. 2) C题: 题意:给定一些数字,要把这些数字方程k行,其中p行和为奇数,剩下和为偶数. 思路:根据奇数偶数的性质,先把p行放1个奇数,然后看看剩下的奇数是不是偶数个,如果不是肯定不满足,然后判断一下剩下的奇数个数/2加上偶数个数是否多余p个,如果不是肯定不满足,然后把这些放入p行,还有剩下的数字就全丢到最后一行去. D题: 题意:给定两个序列,每次操作可以对序列中的数字进行+1或者-1,要使得a序列的最小大于b序列的最大,问最少需要几次操

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 #260 (Div. 2)

A. Laptops 题目意思: 给定n台电脑,第i台电脑的价格是ai ,质量是bi ,问是否存在一台电脑价格比某台电脑价格底,但质量确比某台电脑的质量高,即是否存在ai < aj 且 bi > bj ? 解题思路: 这题一定要看题目,a都是1~n的不同数,b也是1~n的不同数,此题只需要判断ai 是否等于bi ,如果ai != bi 的话,则输出“Happy Alex”,如果所有的ai  == bi 则输出“Poor Alex” 证明:先将a按照从小到大排序,当i<j时ai <

Codeforces Round #260 (Div. 1) A. Boredom (DP)

题目链接:http://codeforces.com/problemset/problem/455/A A. Boredom time limit per test 1 second memory limit per test 256 megabytes input standard input output standard output Alex doesn't like boredom. That's why whenever he gets bored, he comes up with

Codeforces Round #198 (Div. 2)A,B题解

Codeforces Round #198 (Div. 2) 昨天看到奋斗群的群赛,好奇的去做了一下, 大概花了3个小时Ak,我大概可以退役了吧 那下面来稍微总结一下 A. The Wall Iahub and his friend Floyd have started painting a wall. Iahub is painting the wall red and Floyd is painting it pink. You can consider the wall being mad

Codeforces Round #356 (Div. 2) [Codeforces680]

此处有目录↑ Codeforces Round #356(Div. 2):http://codeforces.com/contest/680 A. Bear and Five Cards (贪心) time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output A little bear Limak plays a game. He has