Codeforces Round 871 (Div. 4)(A-G)萌新题解
刚接触算法竞赛的萌新,第一次赛时过了这么多题,虽然div4是真的水 ,随便写个题解(算是题解?)来纪念下
A.Love Story
题意:给定一个字符串,判断其与”codeforces“这个指标串中不匹配的字符的个数
思路:随便写
代码:
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define ull unsigned long long
#define per(i, a, b) for(int i=a;i<=b;i++)
#define rep(i, a, b) for(int i=a,i>=b,i--)
typedef pair<int, int> PII;
const int mod = 1e9 + 7;
const int inf = 0x3f3f3f3f;
void solve() {
string s1,s2;
s1="codeforces";
cin>>s2;
int cnt=0;
for(int i=0;i<s1.size();i++)
{
if(s2[i]!=s1[i])cnt++;
}
cout<<cnt<<endl;
}
signed main() {
std::ios::sync_with_stdio(false);
std::cin.tie(0), cout.tie(0);
int t;
cin >> t;
while (t--)solve();
return 0;
}
B.Blank Space
题意:给定一个只由0,1构成的数组,问最长零串的长度
思路:遍历数组,遇到每个零串都算出这个串的长度,遇到1或者遍历结束的时候更新一下答案
代码:
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define ull unsigned long long
#define per(i, a, b) for(int i=a;i<=b;i++)
#define rep(i, a, b) for(int i=a,i>=b,i--)
typedef pair<int, int> PII;
const int mod = 1e9 + 7;
const int inf = 0x3f3f3f3f;
int a[200];
void solve() {
int n;
cin>>n;
for(int i=1;i<=n;i++)cin>>a[i];
int max1=0;
int cnt=0;
for(int i=1;i<=n;i++)
{
if(a[i]==1)
{
max1=max(cnt,max1);
cnt=0;
}
else{
cnt++;
}
}
max1=max(cnt,max1);
cout<<max1<<endl;
}
signed main() {
std::ios::sync_with_stdio(false);
std::cin.tie(0), cout.tie(0);
int t;
cin >> t;
while (t--)solve();
return 0;
}
C.Mr. Perfectly Fine
题意:某人想学会两种技能,一共有n本书,每本书都要花费一定的时间来学习,每本书里可能学到技能一(第一类),技能二(第二类),技能一加技能二(第三类),或者学不到技能,问需要学会两种技能至少需要的时间,若无解输出-1
思路:分别找到,第一类加第二类,第三类,需要花费的最少时间,输出较小者,(最开始可初始化为inf),注意特判无解情况
代码:
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define ull unsigned long long
#define per(i, a, b) for(int i=a;i<=b;i++)
#define rep(i, a, b) for(int i=a,i>=b,i--)
typedef pair<int, int> PII;
const int mod = 1e9 + 7;
const int inf = 0x3f3f3f3f;
void solve() {
int n;
cin >> n;
int ans1 = inf;
int ans2 = inf;
int ans3 = inf;
for (int i = 1; i <= n; i++) {
int m;
string s;
cin >> m >> s;
if (s == "00")continue;
else if (s == "11")ans1 = min(ans1,m);
else if (s == "10")ans2 = min(ans2,m);
else if (s == "01")ans3 = min(ans3,m);
}
if(min(ans1,ans2+ans3)==inf)cout<<-1<<endl;
else cout<<min(ans1,ans2+ans3)<<endl;
}
signed main() {
std::ios::sync_with_stdio(false);
std::cin.tie(0), cout.tie(0);
int t;
cin >> t;
while (t--)solve();
return 0;
}
D.Gold Rush
题意:对于一个数
n
n
n,不断乘以
2
3
\frac{2}{3}
32或
1
3
\frac{1}{3}
31,问是否可以得到
m
m
m
思路:
首先:
m
>
n
m>n
m>n必定无解
m
=
n
m=n
m=n必定有解
n
m
o
d
3
≠
0
n\ mod\ 3≠0
n mod 3=0必定无解
然后暴力求解即可
代码:
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define ull unsigned long long
#define per(i, a, b) for(int i=a;i<=b;i++)
#define rep(i, a, b) for(int i=a,i>=b,i--)
typedef pair<int, int> PII;
const int mod = 1e9 + 7;
const int inf = 0x3f3f3f3f;
int qpow(int a,int n)
{
int ans=1;
while(n)
{
if(n&1)
{
ans *=a;
}
a*=a;
n>>=1;
}
return ans;
}
void solve() {
int n,m;
cin>>n>>m;
if(m>n){
cout<<"NO"<<endl;
return;
}
if(m==n){
cout<<"YES"<<endl;
return;
}
int cnt=0;
int tmp=n;
while(tmp%3==0)
{
cnt++;
tmp/=3;
}
if(cnt==0)
{
cout<<"NO"<<endl;
return;
}
for(int i=1;i<=cnt;i++)
{
for(int j=0;j<=i;j++)
{
int tmp1=n;
tmp1/=qpow(3,i);
tmp1*=max(qpow(2,j),1ll);
if(tmp1==m)
{
cout<<"YES"<<endl;
return;
}
}
}
cout<<"NO"<<endl;
}
signed main() {
std::ios::sync_with_stdio(false);
std::cin.tie(0), cout.tie(0);
int t;
cin >> t;
while (t--)solve();
return 0;
}
E.The Lakes
题意:给定一个
n
∗
m
n*m
n∗m的湖,
a
[
i
]
[
j
]
a[i][j]
a[i][j]表示每个点的深度,求所有的连通块的最大深度
思路:算是个板子题,可以bfs(但是太弱了不会写),写了个dfs
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define ull unsigned long long
#define per(i, a, b) for(int i=a;i<=b;i++)
#define rep(i, a, b) for(int i=a,i>=b,i--)
typedef pair<int, int> PII;
const int mod = 1e9 + 7;
const int inf = 0x3f3f3f3f;
int dx[5]={0,0,0,1,-1};
int dy[5]={0,1,-1,0,0};
int n,m;
vector<int> ans(2002000);
vector<vector<int> > a(2010,vector<int>(2010));
vector<vector<int> > vis(2010,vector<int>(2010));
void dfs(int x, int y,int cnt)
{
if(vis[x][y]||x<0||x>=n||y<0||y>=m||a[x][y]==0)
{
return;
}
vis[x][y]=1;
ans[cnt]+=a[x][y];
for(int i=1;i<=4;i++)
{
int x1=x+dx[i];
int y1=y+dy[i];
if(x1<0||x1>=n||y1<0||y1>=m)continue;
dfs(x1,y1,cnt);
}
return;
}
void solve() {
cin>>n>>m;
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
vis[i][j]=0;
a[i][j]=0;
}
}
int cnt=-1;
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
cin>>a[i][j];
}
}
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
if(a[i][j]&&!vis[i][j])
{
cnt++;
dfs(i,j,cnt);
}
}
}
int max1=0;
for(int i=0;i<=cnt;i++)
{
max1=max(max1,ans[i]);
ans[i]=0;
}
cout<<max1<<endl;
}
signed main() {
std::ios::sync_with_stdio(false);
std::cin.tie(0), cout.tie(0);
int t;
cin >> t;
while (t--)solve();
return 0;
}
F.Forever Winter
题意:给定一个图的点数n,边数m,以及这些边的连接情况,找到x,y使得(保证有解),中心点连接x个节点,这x个节点除了中心点外又连接了y个节点
思路:观察可知,我们找到每个度为1的点,这些点的个数即为
x
∗
y
x*y
x∗y,然后我们可知,总边数
m
=
x
∗
y
+
x
m=x*y+x
m=x∗y+x,因此,统计出度为1的点即可得出答案
代码:
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define ull unsigned long long
#define per(i, a, b) for(int i=a;i<=b;i++)
#define rep(i, a, b) for(int i=a,i>=b,i--)
typedef pair<int, int> PII;
const int mod = 1e9 + 7;
const int inf = 0x3f3f3f3f;
int deg[200200];
void solve() {
int n,m;
cin>>n>>m;
int cnt=0;
for(int i=1;i<=2000;i++)
{
deg[i]=0;
}
for(int i=1;i<=m;i++)
{
int u,v;
cin>>u>>v;
deg[u]++;
deg[v]++;
}
for(int i=1;i<=n;i++)
{
if(deg[i]==1)cnt++;
}
cout<<m-cnt<<" "<<cnt/(m-cnt)<<endl;
}
signed main() {
std::ios::sync_with_stdio(false);
std::cin.tie(0), cout.tie(0);
int t;
cin >> t;
while (t--)solve();
return 0;
}
G.Hits Different
题意:选择一个位置,把这个位置的罐头取下,计算掉下来的所以罐头的权值和(如图所示)
思路:观察到,答案的区域总是一个矩形,我们可以把图转化成这样:
然后处理出来每个位置的二维前缀和,
对于每次询问,直接
O
(
1
)
O(1)
O(1)回答即可
代码:
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define ull unsigned long long
#define per(i, a, b) for(int i=a;i<=b;i++)
#define rep(i, a, b) for(int i=a,i>=b,i--)
typedef pair<int, int> PII;
const int mod = 1e9 + 7;
const int inf = 0x3f3f3f3f;
int a[3000][3000];
int sum[3000][3000];
int ans[3000000];
void solve() {
int n;
cin>>n;
cout<<ans[n]<<endl;
}
signed main() {
std::ios::sync_with_stdio(false);
std::cin.tie(0), cout.tie(0);
int t;
cin >> t;
int now=1;
for(int i=1;i<=2000;i++)
{
int posx=i;
int posy=1;
while(now<=i*(i+1)/2)
{
a[posx][posy]=now*now;
sum[posx][posy]=sum[posx-1][posy]+sum[posx][posy-1]+a[posx][posy]-sum[posx-1][posy-1];
ans[now]=sum[posx][posy];
now++;
posx--;
posy++;
}
}
while (t--)solve();
return 0;
}