提示:没写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 后,可以进行整理。
- aj−ai=j−i
- aj=j−i+ai
- 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