CF719模拟赛补题报告

本文概述了一场技术竞赛中的解题经历,涉及多个编程题目,如字符串判断、数字构成、矩阵构建等,强调时间管理、解题策略和灵活运用编码技巧的重要性。
摘要由CSDN通过智能技术生成

提示:没写F2,G题,有点难

文章目录

 

  • 比赛分数
  • 二、比赛过程
  • 解题报告
  • 赛事总结

一、比赛分数

A,B,C题AC,其他题没有做。

二v比赛过程

第一题map秒了,第二题其实很简单,但是我看这题数据也不大,就写了个打模拟,挺简单的也过了,第三题其实有很多种方法,是一个很简单的题,竟然废了我1个小时,还是交了一次看第二个样例才发现我太傻了~~~,然后就过了,比赛也结束了。


三、解题报告

1.石头游戏

情况:赛中AC

题意:t 组数据,每一组有一个长度小于50的字符串str (只包含大写字母)

如果有出现一个字母多次出现(连续的不算),就输出 NO, 否则输出 YES。

题解方法:map标记,遇到相同的看看和前面的是否一样。

题解代码:

#include<bits/stdc++.h>
#define CLOSE ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
#define isd(c) ('0' <= (c) && (c) <= '9')
#define isa(c) ('a' <= (c) && (c) <= 'z')
#define isA(c) ('A' <= (c) && (c) <= 'Z')
#define mem(a, b) memset(a, b, sizeof a);
#define N 1000005
#define M 2000005
#define inf 0x3f3f3f3f
#define infll 0x3f3f3f3f3f3f3f3f
#define ll long long
#define ull unsigned long long
#define PI acos(-1)
#define endl "\n"
#define pii pair<long long,long long>
#define F first
#define S second
#define bug cout << endl << " .....here!...." << endl;
//#pragma GCC optimize("O3")
//#define Time (double)clock() / CLOCKS_PER_SEC <= 0.95
//using namespace __gnu_cxx;
//using namespace __gnu_pbds;
using namespace std;
int main(){
	CLOSE;
	ll t;
	cin>>t;
	while(t--){
		map<char,int> mp;
		for(int i=1;i<=26;i++){
			mp['A'+i-1]=0;
		}
		ll n,flag=1;
		string s;
		cin>>n>>s;
		mp[s[0]]=1;
		for(int i=1;i<s.size();i++){
			if(mp[s[i]]==1&&flag==1){
				if(s[i]!=s[i-1]){
					cout<<"NO"<<endl;
					flag=0;
				}
				mp[s[i]]=1;
			}
			else{
				mp[s[i]]=1;
			}
		}
		if(flag==1){
			cout<<"YES"<<endl;
		}
	}
	return 0;
}

2.普通数字

情况:赛中AC

题意:求1~n中所有数中都是由1中数字组成的数。

题解方法:我是枚举位数,然后看看它的范围做的。

题解代码:

#include<bits/stdc++.h>
#define CLOSE ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
#define isd(c) ('0' <= (c) && (c) <= '9')
#define isa(c) ('a' <= (c) && (c) <= 'z')
#define isA(c) ('A' <= (c) && (c) <= 'Z')
#define mem(a, b) memset(a, b, sizeof a);
#define N 1000005
#define M 2000005
#define inf 0x3f3f3f3f
#define infll 0x3f3f3f3f3f3f3f3f
#define ll long long
#define ull unsigned long long
#define PI acos(-1)
#define endl "\n"
#define pii pair<long long,long long>
#define F first
#define S second
#define bug cout << endl << " .....here!...." << endl;
//#pragma GCC optimize("O3")
//#define Time (double)clock() / CLOCKS_PER_SEC <= 0.95
//using namespace __gnu_cxx;
//using namespace __gnu_pbds;
using namespace std;
int main(){
	CLOSE;
	ll t;
	cin>>t;
	while(t--){
		ll n,cnt=0;
		cin>>n;
		if(n<=9){
			cout<<n<<endl;
		}
		else if(n<=99){
			cnt=9;
			cnt+=n/11;
			cout<<cnt<<endl;
		}
		else if(n<=999){
			cnt=18;
			cnt+=n/111;
			cout<<cnt<<endl;
		}
		else if(n<=9999){
			cnt=27;
			cnt+=n/1111;
			cout<<cnt<<endl;
		}
		else if(n<=99999){
			cnt=36;
			cnt+=n/11111;
			cout<<cnt<<endl;
		}
		else if(n<=999999){
			cnt=45;
			cnt+=n/111111;
			cout<<cnt<<endl;
		}
		else if(n<=9999999){
			cnt=54;
			cnt+=n/1111111;
			cout<<cnt<<endl;
		}
		else if(n<=99999999){
			cnt=63;
			cnt+=n/11111111;
			cout<<cnt<<endl;
		}
		else if(n<=999999999){
			cnt=72;
			cnt+=n/111111111;
			cout<<cnt<<endl;
		}
		else if(n<=9999999999){
			cnt=81;
			cnt+=n/1111111111;
			cout<<cnt<<endl;
		}
	}
	return 0;
}

3.不相邻矩阵

情况:赛中AC

题意: 给出 t 组数据,对于每组数据给定一个 n,你需要构造一个n×n 的矩阵,使得相邻的两个数不能是连续的自然数。

题解方法:好多方法,随便选一种就行,我是按斜着排的,角上的两个交换位置。

题解代码:

#include<bits/stdc++.h>
#define CLOSE ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
#define isd(c) ('0' <= (c) && (c) <= '9')
#define isa(c) ('a' <= (c) && (c) <= 'z')
#define isA(c) ('A' <= (c) && (c) <= 'Z')
#define mem(a, b) memset(a, b, sizeof a);
#define N 1000005
#define M 2000005
#define inf 0x3f3f3f3f
#define infll 0x3f3f3f3f3f3f3f3f
#define ll long long
#define ull unsigned long long
#define PI acos(-1)
#define endl "\n"
#define pii pair<long long,long long>
#define F first
#define S second
#define bug cout << endl << " .....here!...." << endl;
//#pragma GCC optimize("O3")
//#define Time (double)clock() / CLOCKS_PER_SEC <= 0.95
//using namespace __gnu_cxx;
//using namespace __gnu_pbds;
using namespace std;
ll a[105][105];
int main() {
	CLOSE;
	ll t;
	cin >> t;
	while (t--) {
		ll n;
		memset(a, 0, sizeof a);
		cin >> n;
		if (n == 1) {
			cout << 1 << endl;
		} else if (n == 2) {
			cout << -1 << endl;
		} else if (n == 3) {
			cout << "2 9 7" << endl;
			cout << "4 6 3" << endl;
			cout << "1 8 5" << endl;
		} else {
			a[1][1]=1;
			ll cnt=n*n-1;
			for(int i=2;i<=n;i++){
				ll k=1;
				for(int j=i;j>=1;j--){
					a[j][k]=cnt;
					k++;
					cnt--;
				}
			}
			for(int i=2;i<=n-1;i++){
				ll k=n;
				for(int j=i;j<=n;j++){
					a[k][j]=cnt;
					k--;
					cnt--;
				}
			}
			a[n][n]=n*n;
			for(int i=1;i<=n;i++){
				for(int j=1;j<=n;j++){
					cout<<a[i][j]<<" ";
				}
				cout<<endl;
			}
		}
	}
	return 0;
}

4.相同的差

情况:赛中WA,补题正确。

题意:给出 T 组序列 a,长度为 N,询问有多少对(i,j) 满足i<j 且 aj​−ai​=j−i。

题解方法:

我们拿到 aj​−ai​=j−i 后,可以进行整理。

  1. aj​−ai​=j−i
  2. aj​=j−i+ai​
  3. aj​−j=ai​−i

接下来,我们发现只需要计算这个数和下标的差就可以知道匹配个数了。

题解代码:

#include<iostream>
#include<algorithm>
#define int long long
using namespace std;
signed main(){
	int t;
	cin>>t;
	while(t--){
		int n;
		cin>>n;
		int a[n+1];
		for(int i=1;i<=n;++i){
			cin>>a[i];
			a[i]-=i;
		}
		int ans=0;
		int m[2*n+1];
		fill(m,m+2*n+1,0);
		for(int i=1;i<=n;++i){
			ans+=m[a[i]+n];
			++m[a[i]+n];
		}
		cout<<ans<<endl;
	}
}

5.排列绵羊

情况:赛中WA,补题正确。

题意:一共有 t 组数据,每组数据第一行为 n ,为字符串长度,下一行为一个字符串(只有 ' . ' 和 ' * '字符),每次可以向右或者向左移动 ‘ * ’ 字符,求把所有的 ' * ' 字符连起来的最小移动次数

题解方法:向中间的羊靠拢是最优解。

题解代码:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
string s;
long long n,m[1000005],pop=0,flag=0,ans=0;
long long t;
int main(){
	cin>>t;
	while(t--){
		pop=0,flag=0,ans=0;
		cin>>n;
		cin>>s;
		for(int i=0; i<n;i++){
			if(s[i]=='*'){
				m[++pop]=i+1;
			}
			if(s[i]=='.') flag=1;
		}
		if(pop==0||pop==1||flag==0) {
			cout<<0<<endl;continue;
		}
		int mid=pop/2+1;
		for(int i=1; i<=pop;i++){
			ans+=abs(m[mid]-m[i])-abs(mid-i);
		}
		cout<<ans<<endl;
	}
	return 0; 
}

6.猜左数第k个0位置 - 简易版 - 交互题

情况:补题正确

题意:交互题。给定n,t,k(由于这里是简单版,保证 t=1),有一个长度为 n 的标号为1⋯n 的仅含 01 的数组,你每次可以询问 l 到 r 的和,需要得出数组中第 k 个 0 的下标。最多询问 20 次。

题解方法:二分

题解代码:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int n,t,k,ans;
int main(){
	cin>>n>>t>>k;
	    int l=1,r=n;
	    for(int l=1,r=n,mid,res;l<=r;){
	        mid=(l+r)/2;
	        cout<<"? 1 "<<mid<<endl;
	        cin>>res;
	        res=mid-res;
	        if(res>=k){
	            ans=mid;
	            r=mid-1;
	        }
	        else{
	            l=mid+1;
	        }
	    }
	    cout<<"! "<<ans<<endl;
	return 0; 
}

四、赛事总结

1.注意分配时间,一些题可能陷入了知识死角。

2.活跃思路,灵活运用方法,掌握做题策略。

THE END

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值