Problem A

思路分析

直接模拟即可 ## AC代码

#include<bits/stdc++.h>
using namespace std;
using ll=long long;
const int MAXN=1e6+10;
void solve(){
int a=0;
string s;
cin>>s;
for(int i=0;i<s.length();i++){
if(s[i]=='A')a++;
}
if(a>5-a)cout<<"A\n";
else cout<<"B\n";
}
int main(){
int t;
cin>>t;
while(t--){
solve();
}
}

Problem B

思路分析

我的思路是:当统计每一行1的个数,当第\(i\)与第\(i-1\)行中统计到的1的个数(前提是这两行中1的个数不为0)不同时,就是三角形,否则是正方形。

一开始的时候WA了一次,就是没考虑到第\(i\)行与第\(i+1\)行中1的个数都得不为0 ## WA代码

#include<bits/stdc++.h>
using namespace std;
using ll=long long;
const int MAXN=12;
void solve(){
int n=0,flag=0;
vector<int> cnt_1(MAXN);
string s;
cin>>n;
for(int i=1;i<=n;i++){
cin>>s;
for(int j=0;j<n;j++){
if(s[j]=='1')cnt_1[i]++;
}
if(i>=2&&cnt_1[i-1]){
if(cnt_1[i-1]!=cnt_1[i]){
flag=1;
}
}
}
if(flag)cout<<"TRIANGLE\n";
else cout<<"SQUARE\n";
}
int main(){
int t;
cin>>t;
while(t--){
solve();
}
}

AC代码

#include<bits/stdc++.h>
using namespace std;
using ll=long long;
const int MAXN=12;
void solve(){
int n=0,flag=0;
vector<int> cnt_1(MAXN);
string s;
cin>>n;
for(int i=1;i<=n;i++){
cin>>s;
for(int j=0;j<n;j++){
if(s[j]=='1')cnt_1[i]++;
}
if(i>=2&&cnt_1[i-1]&&cnt_1[i]){
if(cnt_1[i-1]!=cnt_1[i]){
flag=1;
}
}
}
if(flag)cout<<"TRIANGLE\n";
else cout<<"SQUARE\n";
}
int main(){
int t;
cin>>t;
while(t--){
solve();
}
}

刚刚写博客的时候想到可以改进一下,如果\(flag==1\)了,那么后面的输入其实都是没有意义的,也就不需要统计和判断了,修改如下:

#include<bits/stdc++.h>
using namespace std;
using ll=long long;
const int MAXN=12;
void solve(){
int n=0,flag=0;
vector<int> cnt_1(MAXN);
string s;
cin>>n;
for(int i=1;i<=n;i++){
cin>>s;
for(int j=0;j<n&&!flag;j++){
if(s[j]=='1')cnt_1[i]++;
}
if(i>=2&&cnt_1[i-1]&&cnt_1[i]&&!flag){
if(cnt_1[i-1]!=cnt_1[i]){
flag=1;
}
}
}
if(flag)cout<<"TRIANGLE\n";
else cout<<"SQUARE\n";
}
int main(){
int t;
cin>>t;
while(t--){
solve();
}
}

Problem C

思路分析

其实是一个见过很多次的操作了qwq,先离线处理计算(没错,就是你想的暴力计算\(qwq\))出所有在数据范围内的答案,然后用一个数组将其存下即可。这样可以做到\(O(1)询问\),预处理时间是\(O(MAXN)\),总的时间复杂度为\(O(MAXN+n)\) ## AC代码 具体细节看看代码

#include<bits/stdc++.h>
using namespace std;
using ll=long long;
const int MAXN=2e5+10;
vector<int> ans(MAXN);
int cal(int x){
//将x的各位数字拆解,并统计各位数字总和
int tot=0;
while(x){
tot+=(x%10);
x/=10;
}
return tot;
}
void solve(){
int n;
cin>>n;
//直接输出计算好的ans[n]即可
cout<<ans[n]<<"\n";
}
int main(){
ans[0]=0;
for(int i=1;i<MAXN;i++){
//需要用前缀和数组存下来,因为后面有多次询问,所以需要对应记录哪个i,对应哪个ans[i]
ans[i]=ans[i-1]+cal(i);
}
int t;
cin>>t;
while(t--){
solve();
}
}

Problem D

思路分析

题目的意思:将给的数字分成若干组,同一组中的若干个数字之间,他们的二进制形式的每一位必须都是不同的,求最小组数 我们可以先分析同一组中的数字有什么特点: 在这里插入图片描述 那么我们可以根据这个性质,来求解这道题了,具体还得看代码。 ## AC代码

// LUOGU_RID: 148392530
#include<bits/stdc++.h>
using namespace std;
using ll=long long;
const int MAXN=2e5+10;
void solve(){
int ans=0;
int n;cin>>n;
//book:输入的数字x的个数,可以理解为存放x的库
map<ll,int> book;
for(int i=1;i<=n;i++){
int x;cin>>x;
//查看存放 x对应的异或数(记作y)的库 是否存在
if(book[((1<<31)-1)^x]){
//如果存在,那么book[y]的数量--
book[((1<<31)-1)^x]--;
//说明可以创建出一组满组(也就是有x,y的组),ans++,统计一下
ans++;
}
//否则,book[x]++,说明x库中x的数量增加了一个
else book[x]++;
}
//再遍历一下无法找到 对应的y 的x,那么他们只能单独成组了
for(auto x:book){
ans+=x.second;
}
cout<<ans<<"\n";
}
int main(){
int t;
cin>>t;
while(t--){
solve();
}
}

Problem E

思路分析

可以先模拟一下题目说的流程: 在这里插入图片描述 ## AC代码

#include<bits/stdc++.h>
using namespace std;
using ll=long long;
const int MAXN=2e5+10;
void solve(){
int n,k;cin>>n>>k;
int cnt=0;
//注意得向上取整
while(k>(n+1)/2){
int tot=(n+1)/2;
k-=tot;
//注意总数/2
n/=2;
//轮数++
cnt++;
}
//说实话,我也没太懂为什么是2*k-1
//owo 我们每一次删除的时候删的是K*(1,3,5······),所以这里2*k-1,才是对应删的奇数(K泛指系数)
cout<<((2*k-1)<<cnt)<<"\n";
}
int main(){
ios::sync_with_stdio(0);
int t;
cin>>t;
while(t--){
solve();
}
}