【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;
}

CF总结

1、CF的题目还是偏思维,练习CF可以增加赛场感和提高思维力,如果想练习算法还是要另外刷题。
2、对于简单的题目写炸了,不要慌张,仔细想想细节实现的问题,如果暂时想不出来就换题,后面的分数比前面的多。
3、赛后记得复盘,并且可以的话把后面没写的题目尽量刷一刷,不然用用写不到后面的题。
4、对于简单题,要看清题目,提高出题速度和准确性。
posted @ 2020-11-18 21:48  Shayndel  阅读(127)  评论(0编辑  收藏  举报