【CF1447】div2复盘
CF1447 div2 复盘
A. Add Candies
题意
签到题,给n个数,以1-n排列,每次操作可以把除第i个数加a[i]个,求数组a[i]的个数和输出a[i]
思路
显然,我们只要输出n和n-1就好。
真·读题十分钟·代码三十秒
B. Numbers Box
题意
给一个n*m的矩阵,相邻两个数可以变成他们的相反数,问矩阵最大的和是多少。
思路
显然,统计矩阵中负数的个数,如果是偶数,那就一定可以全部转成正的,只要输出矩阵元素的绝对值和sum就好。如果是奇数,就找绝对值最小的,答案就是sum-2×max
这道题我一开始写炸了,因为考虑到了零的因素,一直在考虑找零边上最小的负数,这就导致WA
代码
#include <bits/stdc++.h>
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <map>
#include <algorithm>
#include <cmath>
#define ll long long
#define ull unsigned long long
using namespace std;
inline int read(){
int f=0,num;
char ch;
while(ch=getchar(),!isdigit(ch))if(ch=='-')f=1;num=ch-'0';
while(ch=getchar(), isdigit(ch))num=num*10+ch-'0';
return f?-num:num;
}
int g[13][13];
int main(){
int T,n,m;
T=read();
while(T--){
int minn=1000;
m=read();n=read();
int cnt=0,sum=0;
for(int i=0;i<m;i++){
for(int j=0;j<n;j++){
g[i][j]=read();
if(g[i][j]<0){
sum-=g[i][j];
cnt++;
minn=min(minn,-g[i][j]);
}
else{
sum+=g[i][j];
minn=min(minn,g[i][j]);
}
}
}
if(cnt%2)sum-=minn*2;
cout<<sum<<endl;
}
return 0;
}
C.Knapsack
题意
给你n个物品,每个物品的重量是w[i],限定重量是W,要求 物品重量之和为C满足[W/2,W],输出物品数量和物品的重量
思路
对于第i个物品,如果w[i]>(W+1)/2 直接输出1 和这个物品的重量
如果w[i]>W 输出-1
如果sum>(W+1)/2 则保存和内的所有元素
代码实现
#include <bits/stdc++.h>
#define ll long long
#define ull unsigned long long
using namespace std;
inline ll read(){
ll f=0,num;
char ch;
while(ch=getchar(),!isdigit(ch))if(ch=='-')f=1;num=ch-'0';
while(ch=getchar(), isdigit(ch))num=num*10+ch-'0';
return f?-num:num;
}
const int N=2e5+3;
ll anss[N];
int main(){
ll T;
T=read();
while(T--){
ll n,w;
n=read();w=read();
ll sum=0,cnt=0;
int f=0;
int ans=0;
for(int i=1;i<=n;i++) {
ll t=read();
if(f)continue;
if(t>w)continue;
else{
if(t>(w+1)/2){
f=1;
ans=i;
}
if(f==1)continue;
anss[++cnt]=i;
sum+=t;
if(sum>=(w+1)/2)
f=2;
}
}
if(f==0)cout<<"-1"<<endl;
else if(f==1){
cout<<"1"<<endl;
cout<<ans<<endl;
}
else if(f==2){
cout<<cnt<<endl;
for(int i=1;i<=cnt;i++)
cout<<anss[i]<<" ";
cout<<endl;
}
}
return 0;
}
这题深刻地让我体会到,眼睛没有用可以给有需要的人。WA了第一个点,把我弄蒙了。
我错哪了我错哪了
在比赛结束前最后一分钟发现,最后要输出元素的个数,我没有输出。改完之后提交的时候,CF卡了,比赛结束QAQ
第二天补题的时候就过了
西湖的水我的泪啊!!!
下次一定要长眼睛呜呜呜
D.Catching Cheaters
题意
给长度为n,m的字符串AB,对于他们的字串C,D
输出最大的S(C,D)S(C,D)S(C,D)
S(C,D)=4×LCS(C,D)−∣C∣−∣D∣
思路
显然这可以用dp做
dp[i][j]表示以A[i]为结尾的字串和以B[j]为结尾的字串的S值
A[i]==B[j]时dp[i][j]=max(dp[i][j],dp[i-1][j-1]+2)
dp[i][j]=max(max(0,dp[i][j]),max(dp[i-1][j]-1,dp[i][j-1]-1));
代码
#include <bits/stdc++.h>
#define ll long long
#define ull unsigned long long
using namespace std;
inline int read(){
int f=0,num;
char ch;
while(ch=getchar(),!isdigit(ch))if(ch=='-')f=1;num=ch-'0';
while(ch=getchar(), isdigit(ch))num=num*10+ch-'0';
return f?-num:num;
}
const int N=5e3+7;
int n,m;
int dp[N][N];
string A, B;
int main() {
int res = 0;
n=read();m=read();
cin>>A>>B;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if(A[i-1]==B[j-1]) {
dp[i][j]=dp[i-1][j-1]+2;
}
dp[i][j]=max(max(0,dp[i][j]),max(dp[i-1][j]-1,dp[i][j-1]-1));
res=max(res,dp[i][j]);
}
}
cout<<res<<endl;
return 0;
}