A:http://codeforces.com/contest/1447/problem/A
解析:
直接输出n个数,1~n即可。
#include<iostream> #include<cstdio> #include<cstdio> #include<cstring> #include<algorithm> #include<queue> using namespace std; int main() { int t; cin>>t; while(t--) { int n; cin>>n; cout<<n<<endl; for(int i=1;i<=n;i++) cout<<i<<" "; cout<<endl; } }
B:http://codeforces.com/contest/1447/problem/B
题意:
操作:找一组相邻格子,里面的数都乘-1
求矩阵最大和,操作数不限。
解析:
对于-1,应该有这种思维:一个数乘两次-1,不变。
举个例子,我想改变-1:
-1 2
3 4
-1,2乘-1,那么有:
1 -2
3 4
-2,4乘-1,那么有:
1 2
3 -4
可以发现,要改变一个数,只需要在矩阵的任意一个位置找一个数和它一起乘-1即可,不一定需要相邻。因为相邻的话,经过层层转嫁,可以把影响换到任意一个位置。
根据贪心,我们要改变的,就是负数。
把<=0的全收集起来,排个序,数目记为cnt。因为每次要改变一对数,所以如果cnt是偶数的话,里面的数全可以变成正数。
cnt为奇数的话,奇数-1是偶数,把偶数部分变正,那么此时还剩最后一个负数,改变它是有可能增加总体和的,所以把正数那边的最小值找到,和这个负数的绝对值比较一下,看一下是否能增加总体和。
#include<iostream> #include<cstdio> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #include<queue> using namespace std; const int maxn=111; int a[maxn][maxn]; int b[maxn]; const int minn=999999; int main() { int t; cin>>t; while(t--) { int n; int m; cin>>n>>m; int sum=0; int minx=minn; int all=0,tot=0; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) { cin>>a[i][j]; if(a[i][j]>0) all+=a[i][j]; else b[tot++]=a[i][j]; } sort(b,b+tot); if(tot%2==0) { for(int i=tot-1;i>=0;i--) sum+=fabs(b[i]); } else { int maxx=-minn; for(int i=0;i<tot-1;i++) sum+=fabs(b[i]); int ok=0; for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) { if(a[i][j]>0&&a[i][j]<minx) { minx=min(minx,a[i][j]); ok=1; } } } if(!ok) { sum+=b[tot-1]; } else if(fabs(b[tot-1])>minx) { sum+=fabs(b[tot-1]); all-=2*minx;//这里要注意 // cout<<all<<endl; } else { sum+=b[tot-1]; } } cout<<sum+all<<endl; } } //33 //2 2 //3 4 //-5 1
C:http://codeforces.com/contest/1447/problem/C
题意:
给出n个小包,每个包含wi个。给出总容量W,
能否用一些小包,使得它们的容量>=W/2&&<=W
解析:
把<=W的收集起来。
从大到小排序,从大往小贪心即可。
不能从小到大贪心,比如:
3 11
2 3 7
从小的话,无解,但是从大的话就有解。
#include<cstdio> #include<cstring> #include<vector> #include<set> #include<algorithm> #include<iostream> #include<vector> using namespace std; typedef long long ll; const int maxn=2e5+10,maxn2=31*maxn; int b[maxn]; int tot=0; struct node { ll val; int id; }st[maxn]; bool cmp(node a,node b) { return a.val>b.val; } int main() { int t; cin>>t; while(t--) { int n,tot=0; ll w; cin>>n>>w; for(int i=1;i<=n;i++) { ll x; cin>>x; if(x<=w) { tot++; st[tot].val=x; st[tot].id=i; } } sort(st+1,st+1+tot,cmp); ll sum=0; int tot2=0; for(int i=1;i<=tot;i++) { if(sum+st[i].val>w) continue; sum+=st[i].val; b[tot2++]=st[i].id; } sort(b,b+tot2); if(sum*2<w) cout<<"-1"<<endl; else { cout<<tot2<<endl; for(int i=0;i<tot2;i++) cout<<b[i]<<" "; cout<<endl; } } return 0; }