Codeforces Round 871 (Div. 4)
A. Love Story
#include<bits/stdc++.h>
using namespace std;
#define int long long
int read() {
int x = 0, f = 1, ch = getchar();
while ((ch < '0' || ch > '9') && ch != '-') ch = getchar();
if (ch == '-') f = -1, ch = getchar();
while (ch >= '0' && ch <= '9') x = (x << 3) + (x << 1) + ch - '0', ch = getchar();
return x * f;
}
void solve(){
string s;
cin >> s;
int res = 0;
for( int i = 0 ; i < s.size() ; i ++ )
res += s[i] != "codeforces"[i];
cout << res <<"\n";
return;
}
int32_t main() {
for( int t = read() ; t ; t -- )
solve();
return 0;
}
B. Blank Space
#include<bits/stdc++.h>
using namespace std;
#define int long long
int read() {
int x = 0, f = 1, ch = getchar();
while ((ch < '0' || ch > '9') && ch != '-') ch = getchar();
if (ch == '-') f = -1, ch = getchar();
while (ch >= '0' && ch <= '9') x = (x << 3) + (x << 1) + ch - '0', ch = getchar();
return x * f;
}
void solve(){
int n = read() , res = 0 , cnt = 0;
for( int x ; n ; n -- ){
x = read();
if( x == 1 ) cnt = 0;
else cnt ++ , res = max( res , cnt );
}
printf("%lld\n" , res);
return;
}
int32_t main() {
for( int t = read() ; t ; t -- )
solve();
return 0;
}
C. Mr. Perfectly Fine
dp一下就好了
#include<bits/stdc++.h>
using namespace std;
#define int long long
int read() {
int x = 0, f = 1, ch = getchar();
while ((ch < '0' || ch > '9') && ch != '-') ch = getchar();
if (ch == '-') f = -1, ch = getchar();
while (ch >= '0' && ch <= '9') x = (x << 3) + (x << 1) + ch - '0', ch = getchar();
return x * f;
}
void solve(){
int n = read();
vector<int> f( 4 , 1e18 ) , g;
f[0] = 0;
for( int x , y ; n ; n -- ){
x = read() , y = read();
if( y > 1 ) y -= 8;
g = f;
for( int i = 0; i < 4 ; i ++ )
f[i|y] = min( f[i|y] , g[i] + x );
}
if( f[3] == 1e18 ) printf("-1\n");
else printf("%lld\n" , f[3] );
return;
}
int32_t main() {
for( int t = read() ; t ; t -- )
solve();
return 0;
}
D. Gold Rush
只有当前的数字是三的倍数才可以分。最多可以分\(\log_3n\)次,为了避免重复的情况可以加一个记忆化
#include<bits/stdc++.h>
using namespace std;
#define int long long
int read() {
int x = 0, f = 1, ch = getchar();
while ((ch < '0' || ch > '9') && ch != '-') ch = getchar();
if (ch == '-') f = -1, ch = getchar();
while (ch >= '0' && ch <= '9') x = (x << 3) + (x << 1) + ch - '0', ch = getchar();
return x * f;
}
int n , m , f = 0;
set<int> vis;
void dfs( int x ){
if( f == 1 || x < m || vis.count(x) ) return;
if( x == m ){
f = 1;
return;
}
if( x % 3 ) return;
dfs( x / 3 ) , dfs( x / 3 * 2 );
return;
}
void solve(){
n = read() , m = read() , f = 0;
dfs(n);
cout << ( f ? "yes\n" : "no\n");
return;
}
int32_t main() {
for( int t = read() ; t ; t -- )
solve();
return 0;
}
E. The Lakes
就搜一下就好了吧。
#include<bits/stdc++.h>
using namespace std;
#define int long long
int read() {
int x = 0, f = 1, ch = getchar();
while ((ch < '0' || ch > '9') && ch != '-') ch = getchar();
if (ch == '-') f = -1, ch = getchar();
while (ch >= '0' && ch <= '9') x = (x << 3) + (x << 1) + ch - '0', ch = getchar();
return x * f;
}
constexpr int dx[] = { 0 , 0 , 1 , -1 };
constexpr int dy[] = { 1 , -1 , 0 , 0};
void solve(){
int n = read() , m = read() , res = 0;
vector<vector<int>> g(n+1,vector<int>(m+1 , 0));
for(int i = 1 ; i <= n ; i ++ )
for( int j = 1 ; j <= m ; j ++ )
g[i][j] = read();
vector<vector<bool>> vis( n+1 , vector<bool>(m+1 , 0) );
for( int i = 1 ; i <= n ; i ++ )
for( int j = 1 ; j <= m ; j ++ ){
if( vis[i][j] || g[i][j] < 1 ) continue;
int cnt = 0;
queue<pair<int,int>> q;
q.emplace( i , j );
while( !q.empty() ){
auto [x,y] = q.front();
q.pop();
if( vis[x][y] ) continue;
vis[x][y] = 1 , cnt = cnt + g[x][y];
for( int l = 0 , fx , fy ; l < 4 ; l ++ ){
fx = x + dx[l] , fy = y + dy[l];
if( fx < 1 || fy < 1 || fx > n || fy > m || g[fx][fy] < 1 || vis[fx][fy] ) continue;
q.emplace(fx , fy);
}
}
res = max( res , cnt );
}
printf("%lld\n" , res );
return;
}
int32_t main() {
for( int t = read() ; t ; t -- )
solve();
return 0;
}
F. Forever Winter
因为题目保证了\(x>1,y>1\)所以度为 1 的点一定是叶子节点。从叶子点向内走一步就是第一次扩展的点,在走一步就是根节点。然后根据度数计算\(x,y\)
#include <bits/stdc++.h>
using namespace std;
#define int long long
int read() {
int x = 0, f = 1, ch = getchar();
while ((ch < '0' || ch > '9') && ch != '-') ch = getchar();
if (ch == '-') f = -1, ch = getchar();
while (ch >= '0' && ch <= '9') x = (x << 3) + (x << 1) + ch - '0', ch = getchar();
return x * f;
}
const int N = 1e6 + 5, M = 1505;
int pos[M][M], px[N], py[N];
int sum(int x) {
return x * (x + 1) * (x * 2 + 1) / 6;
}
void solve() {
int n = read() , m = read();
vector<vector<int>> g(n+1);
for( int u , v ; m ; m -- ){
u = read() , v = read();
g[u].push_back(v) , g[v].push_back(u);
}
int x , y;
for( int i = 1 ; i <= n ; i ++ ){
if( g[i].size() != 1 ) continue;
x = g[i].front();
for( auto v : g[x] ){
if( g[v].size() != 1 ) y = v;
}
x = g[x].size() - 1 , y = g[y].size();
printf("%lld %lld\n" , y , x);
break;
}
}
int32_t main() {
for (int t = read(); t; t--)
solve();
return 0;
}
G. Hits Different
一个比较简单的模拟。首先要知道\(1^2+2^2+3^2+\cdots+n^2=\frac{n(n-1)(2n-1)}{6}\)
所以只要计算出每一层的左右端点即可。
#include <bits/stdc++.h>
using namespace std;
#define int long long
int read() {
int x = 0, f = 1, ch = getchar();
while ((ch < '0' || ch > '9') && ch != '-') ch = getchar();
if (ch == '-') f = -1, ch = getchar();
while (ch >= '0' && ch <= '9') x = (x << 3) + (x << 1) + ch - '0', ch = getchar();
return x * f;
}
const int N = 1e6 + 5, M = 1505;
int pos[M][M], px[N], py[N];
int sum(int x) {
return x * (x + 1) * (x * 2 + 1) / 6;
}
void solve() {
int n = read(), res = 0;
for (int i = px[n], l = py[n], r = py[n]; i >= 1; i--) {
res += sum(pos[i][r]) - sum(pos[i][l] - 1);
l = max(1ll, l - 1), r = min(r, i - 1);
}
printf("%lld\n", res);
}
int32_t main() {
for (int i = 1, t = 0; t <= 1e6; i++)
for (int j = 1; j <= i && t <= 1e6; j++)
t++, pos[i][j] = t, px[t] = i, py[t] = j;
for (int t = read(); t; t--)
solve();
return 0;
}
H. Don't Blame Me
f[i][j]
表示前 i 位的非空子序列凑出 j 的方案数。所以只要枚举每一个选或不选,再枚举每一个数的前一个数即可。但是注意的是\(f[i][j]\)无法表示全空的情况,但是又会有前 i 个只选a[i]
的情况,这种情况无法从之前的状态转移得来,所以f[i][a[i]]
要单独加 1
#include <bits/stdc++.h>
using namespace std;
#define int long long
int read(){
int x = 0 , f = 1 , ch = getchar();
while( (ch < '0' || ch > '9') && ch != '-' ) ch = getchar();
if( ch == '-' ) f = -1 , ch = getchar();
while( ch >= '0' && ch <= '9' ) x = ( x << 3 ) + ( x << 1 ) + ch - '0' , ch = getchar();
return x * f;
}
const int mod = 1e9+7;
void solve(){
int n = read() , k = read();
vector<vector<int>> f( n+1 , vector<int>(64 , 0) );
for( int i = 1 , x ; i <= n ; i ++ ) {
x = read();
f[i][x] ++;
for( int j = 0 ; j < 64 ; j ++ )
f[i][j] = ( f[i][j] + f[i-1][j] ) % mod;
for( int j = 0 ; j < 64 ; j ++ )
f[i][j&x] = ( f[i][j&x] + f[i-1][j] ) % mod;
}
int res = 0;
for( int i = 0 ; i < 64 ; i ++){
auto t = bitset<6>(i);
if( t.count() == k ) res = ( res + f[n][i] ) % mod;
}
printf("%lld\n" , res );
}
int32_t main() {
for( int t = read() ; t ; t -- )
solve();
}