Codeforces Round #806 (Div. 4) A-F题解及代码
A. YES or YES?
题意及要求:给定**均为小写字母且长度为
3
**的字符串,判断它是否为"YES
",同时"yES
",“Yes
”,"yes
"都是满足答案的。思路:字面意思的题目不解释。
代码:
#include<bits/stdc++.h>
#define IOS std::ios::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
#define ll long long
#define int long long
#define endl "\n"
using namespace std;
const int mn = 1e5+10;
const int mod = 1e9+7;
const int N = 2e5+10;
int dr[4][2]={{-1,0},{1,0},{0,-1},{0,1}};
void solve(){
string s;
cin >>s;
if((s[0]=='Y'||s[0]=='y')&&(s[1]=='E'||s[1]=='e')&&(s[2]=='s'||s[2]=='S')){
cout <<"YES"<<endl;
}else{
cout <<"NO"<<endl;
}
}
signed main(){
IOS;
int T=1;
cin >>T;
while(T--){
solve();
}
return 0;
}
B. ICPC Balloons
题意:在ICPC比赛中,每做出来一个题目,队伍将得到一个气球,完成此题的队伍是第一个做出来此题的,则得到一个额外的气球。
要求:现给定一个字符串,用A,B,C…,Z表示26个题目,第
i
个字符表示该问题已经被某个团队解决(没有队伍会两次解决同一个问题),求此次比赛共有多少个气球。思路:遍历此字符串的每个字符,若这个字符是第一次出现,则气球数量+2,若不是第一次出现,则气球数量+1。
代码:
#include<bits/stdc++.h>
#define IOS std::ios::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
#define ll long long
#define int long long
#define endl "\n"
using namespace std;
const int mn = 1e5+10;
const int mod = 1e9+7;
const int N = 2e5+10;
int dr[4][2]={{-1,0},{1,0},{0,-1},{0,1}};
void solve(){
map<char,bool> mp;
int n;
string s;
cin >>n>>s;
int ans = 0;
for(int i=0;i<s.length();i++){
if(mp[s[i]]==false){//标记第一次,气球数量+2
mp[s[i]]=true;
ans+=2;
}else{ //非第一次,则气球数量+1
ans++;
}
}
cout <<ans<<endl;
}
signed main(){
IOS;
int T=1;
cin >>T;
while(T--){
solve();
}
return 0;
}
C. Cypher
题意:有一个密码锁,如下图,他的密码区域是可旋转的,可以执行下面两种操作:
- 向上转动(以字符U来表示):将密码数字增加
1
,但将9
向上转动后,则会变成0
。- 向下转动(以字符D来表示):将密码数字减少
1
,但将0
向下转动后,则会变成9
。要求:给出最终的密码,以及轮子的若干移动方向,求出原始密码。
思路:字面意思,反过来求解原始密码。
代码:
#include<bits/stdc++.h>
#define IOS std::ios::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
#define ll long long
#define int long long
#define endl "\n"
using namespace std;
const int mn = 1e5+10;
const int mod = 1e9+7;
const int N = 2e5+10;
int dr[4][2]={{-1,0},{1,0},{0,-1},{0,1}};
int a[mn];
void solve(){
int n;
cin >>n;
for(int i=1;i<=n;i++){
cin >>a[i];
}
for(int i=1;i<=n;i++){
int num;
cin >>num;
int ans = a[i];
for(int i=1;i<=num;i++){
char x;
cin >>x;
if(x=='D'){ //如果向下转动,则原始密码应+1;
ans++;
}else{ //如果向下转动,则原始密码应-1;
ans--;
}
if(ans==-1){
ans=9;
}
if(ans==10){
ans=0;
}
}
cout <<ans<<" ";
}
cout <<endl;
}
signed main(){
IOS;
int T=1;
cin >>T;
while(T--){
solve();
}
return 0;
}
D.Double Strings
题意及要求:给出
n
个字符串,每个字符串长度不超过8
;对于每个字符串,若它可以由其他两个字符串(可以是相同的字符串)拼接起来,则输出1
,否则输出0
。思路:
若将每个字符串暴力判断,则时间复杂度为
O(n^2)
,会TLE。但是若将字符串用map标记存储,再将每个字符串判断,则可以将时间复杂度降低到
O(n*length)
。
代码:
#include<bits/stdc++.h>
#define IOS std::ios::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
#define ll long long
#define int long long
#define endl "\n"
using namespace std;
const int mn = 1e5+10;
const int mod = 1e9+7;
const int N = 2e5+10;
int dr[4][2]={{-1,0},{1,0},{0,-1},{0,1}};
string a[mn];
void solve(){
map<string,bool> mp;
int n;
cin >>n;
for(int i=1;i<=n;i++){
cin >>a[i];
mp[a[i]]=true;
}
for(int i=1;i<=n;i++){
bool pd = true;
if(pd)
for(int j=0;j<a[i].length();j++){
string s1="",s2="";
for(int l=0;l<=j;l++){
s1+=a[i][l];
}
for(int l=j+1;l<a[i].length();l++){
s2+=a[i][l];
}
if(mp[s1]&&mp[s2]&&pd){//拆分后若两个字符串均存在,则输出1
cout <<1;
pd=false;
}
}
if(pd) cout <<0;
}
cout <<endl;
}
signed main(){
IOS;
int T=1;
cin >>T;
while(T--){
solve();
}
return 0;
}
E. Mirror Grid
题意:存在一个
n行
*n列
的矩阵,每一个格子存在一个数字,你每次可以将任意一个格子的数字变化(将0
变成1
或将1
变成0
)。
要求:你将进行若干次变化,求一个最小次数的变化后,这个矩阵进行0度
,90度
,180度
,270度
旋转后矩阵不变;思路:将矩阵分为四
4
个,判断左上角这个矩阵中每个格子旋转各个角度所对应的格子(共四个)中0
和1
的数量,若:
0
的数量少:则将这些格子全部变成1
,次数+四个格子中0的数量
1
的数量少:则将这些格子全部变成0
,次数+四个格子中1的数量
代码:
#include<bits/stdc++.h>
#define IOS std::ios::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
#define ll long long
#define int long long
#define endl "\n"
using namespace std;
const int mn = 1e5+10;
const int mod = 1e9+7;
const int N = 2e5+10;
int dr[4][2]={{-1,0},{1,0},{0,-1},{0,1}};
int a[200][200];
void solve(){
int n;
cin >>n;
for(int i=1;i<=n;i++){
string s;
cin >>s;
for(int j=0;j<s.length();j++){
a[i][j+1]=s[j]-'0';
}
}
int nn;
if(n&1) nn=(n+1)/2;
else nn = n / 2;
int ans = 0;
for(int i=1;i<=nn;i++){
for(int j=1;j<=nn;j++){
int num_0 = 0,num_1 = 0;
if(a[i][j]==1) { num_1++; }
else { num_0++; }
if(a[j][n-i+1]==1) { num_1++; }
else { num_0++; }
if(a[n-i+1][n-j+1]==1) { num_1++; }
else { num_0++; }
if(a[n-j+1][i]==1) { num_1++; }
else { num_0++; }
if(num_1<=num_0){
a[i][j]=0;
a[j][n-i+1]=0;
a[n-i+1][n-j+1]=0;
a[n-j+1][i]=0;
ans+=num_1;//其实只有这行代码有用,为了顺应上述思路,写出了上面四行改变格子的值
}else{
a[i][j]=1;
a[j][n-i+1]=1;
a[n-i+1][n-j+1]=1;
a[n-j+1][i]=1;
ans+=num_0;//其实只有这行代码有用,为了顺应上述思路,写出了上面四行改变格子的值
}
}
}
cout <<ans<<endl;
}
signed main(){
IOS;
int T=1;
cin >>T;
while(T--){
solve();
}
return 0;
}
F. Yet Another Problem About Pairs Satisfying an Inequality
题意及要求:给出
n
个数组a1
,a2
,…
,an
,求有多少个满足ai < i < aj < j
(i
和j
为下标)。思路:将满足
ax < x
的下标记录下来,然后将这些记录下来的下标所对应的值ax
与这些下标进行比较,每有一个大于坐标的值,答案+1;故我们用树状数组记录下标。
代码:
#include<bits/stdc++.h>
#define IOS std::ios::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
#define ll long long
#define int long long
#define endl "\n"
using namespace std;
const int mn = 1e5+10;
const int mod = 1e9+7;
const int N = 2e5+10;
int dr[4][2]={{-1,0},{1,0},{0,-1},{0,1}};
int n = 262144;
int d[262145];
int a[N];
int lowbit(int x){
return x&(-x);
}
int query(int x){
int res=0;
while(x){
res+=d[x];
x-=lowbit(x);
}
return res;
}
void update(int x,int v){
while(x<=n){
d[x]+=v;
x+=lowbit(x);
}
}
void solve(){
memset(d,0,sizeof(d));
vector<int> t;
int n;
cin >>n;
for(int i=1;i<=n;i++){
cin >>a[i];
if(a[i]<i){
update(i+1,1);
t.push_back(i);
}
}
int ans = 0;
for(int i=0;i<t.size();i++){
ans+=query(a[t[i]]);
}
cout <<ans<<endl;
}
signed main(){
IOS;
int T=1;
cin >>T;
while(T--){
solve();
}
return 0;
}