A. Add Candies
题目链接:A题
题目大意:
共有n个包裹,第i个包裹初始时装有i颗糖果
你可以选择m次操作(m由自己决定),在第j次操作时指定某一个包裹不放糖果,其它包裹每个包裹装入j颗糖果
目的:使所有包裹糖果数相同
思路:
n次操作,在第j次操作时,指定第j个包裹即可
例:n为3时
第一轮指定1号包裹,第二轮指定2号包裹,第三轮指定3号包裹,则最终每个包裹都是1+2+3颗糖果
代码:
#include <iostream>
#include <cstdio>
using namespace std;
int main()
{
int t;
scanf("%d",&t);
while(t--){
int n;
scanf("%d",&n);
printf("%d\n",n);
for(int i=1;i<n;i++)
printf("%d ",i);
printf("%d\n",n);
}
return 0;
}
B.Numbers Box
题目链接:B题
题目大意:
n*m的矩阵,每次操作可以让矩阵中相邻的两个元素的值同时乘上-1,你可以操作任意次,问你矩阵所有元素的和sum的值最大为多少
思路:
如果矩阵中值为负数的元素有偶数个,则一定都能将它们变为正值,如果矩阵中有0也可以,否则不管怎么消除,都会有一个元素始终为负值,在这种情况下选择绝对值最小的为负值就行
代码:
#include <iostream>
#include <cstdio>
#include <string.h>
#include <string>
#include <algorithm>
#include <math.h>
using namespace std;
int main()
{
int t;
scanf("%d",&t);
while(t--){
int n,m;
scanf("%d%d",&n,&m);
int num=0;
int abs_min=100000;
int ans=0;
int flag=0;
for(int i=0;i<n;i++)
for(int j=0;j<m;j++){
int temp;
scanf(" %d",&temp);
ans+=abs(temp);
if(temp==0) flag=1;
if(temp<0) num++;
abs_min=min(abs_min,abs(temp));
}
if(num%2&&!flag) ans-=2*abs_min;
printf("%d\n",ans);
}
return 0;
}
C. Knapsack
题目链接:C题
题目大意:
给你n件物品,每件物品质量为wi,一个容量为W的背包,让你选择一种方案使物品的质量和大于W的一半且不能超过W
思路:
在n件物品中,质量大于w的物品我们肯定不会选,没有意义,所以直接不考虑它。如果有质量大于W的一半而小于W的物品,那我们只选这个物品就行。
也就是说现在考虑x个物品,每个物品质量都小于W的一半,要求它们的和超过W的一半的方案。
将所有物品质量从小到大排序,然后累加到质量和大于W的一半即可,因为没有一个物品的质量会大于W的一半,所以不用考虑加上这个物品后质量会超过W。
然后再判断一下质量和小于W的一半的情况,输出-1(无方案)即可
代码:
#include <iostream>
#include <cstdio>
#include <string.h>
#include <string>
#include <algorithm>
#include <math.h>
using namespace std;
typedef struct{
long long number;
int index;
}node;
node num[200010];
bool cmp(node a,node b){
return a.number<b.number;
}
int main()
{
int t;
scanf("%d",&t);
while(t--){
long long n,W;
scanf("%lld%lld",&n,&W);
long long low=(W+1)/2;
int flag=0,ans,cnt=0;
for(long long i=1;i<=n;i++){
long long temp;
scanf(" %lld",&temp);
if(temp>W) continue;
if(temp>=low) flag=1,ans=i;
num[cnt].number=temp;
num[cnt++].index=i;
}
if(flag) {printf("1\n%d\n",ans);continue;}
sort(num,num+cnt,cmp);
int pos;
long long s=0;
for(int i=0;i<cnt;i++){
s+=num[i].number;
if(s>=low){
pos=i;
break;
}
}
if(s<low) {printf("-1\n");continue;}
printf("%d\n",pos+1);
for(int i=0;i<=pos;i++)
i==pos?printf("%d\n",num[i].index):printf("%d ",num[i].index);
}
return 0;
}