开头 :
这场没打,今天vp了一下,写了A-G,然后就去吃饭了!
比赛链接 :
Dashboard - Codeforces Round 952 (Div. 4) - Codeforces
A
直接交换,输出即可
inline void solve(){
string a , b ; cin >> a>> b ;
char c = a[0] ;
a[0] = b[0] ;
b[0] = c ;
cout << a << " " << b << endl ;
}
B
数据范围小,模拟那个过程即可;
#include<bits/stdc++.h>
#define IOS ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
using namespace std;
typedef long long LL;
typedef unsigned long long ULL ;
#define PI acos(-1)
#define endl '\n'
#define pair<int,int> PII ;
#define x first
#define y second
#define no do { cout << "No" << endl; return; } while(0)
#define yes do { cout << "Yes" << endl; return; } while (0)
#define lowbit(x) ((x) & -(x))
#define rep(i, s, e) for (int i=(s);i<(e);++i)
#define all(v) v.begin(), v.end()
#define pb push_back
const LL INF = 1e18 ;
const int mod = 1e9+7;
const int N = 2e5+10;
int dx[4] = {0, 1, 0, -1}, dy[5] = {1, 0, -1, 0};
LL gcd(LL a, LL b) {
return b ? gcd(b, a % b) : a;
}
LL qmi(int m, int k, int p){
int res = 1 % p, t = m;
while (k){
if (k&1) res = res * t % p;
t = t * t % p;
k >>= 1;
}
return res;
}
inline void solve(){
int n ; cin >> n ;
int ans = 0 ,yss = 1 ;
rep(i,2,n+1){
int x = i ;
int res = 0 ;
while(x<=n){
res += x ;
x += i ;
}
if(res>ans) {
ans = res ;
yss = i ;
}
}
cout << yss << endl ;
}
signed main(){
IOS
int _ = 1;
cin >> _;
while(_ --) solve();
return 0;
}
C
也是模拟遍历,先用前缀和预处理一下;
如果ma * 2 = b[i],表示a[1,i]是满足题目条件的;
inline void solve(){
int n ; cin >> n ;
rep(i,1,n) cin >> a[i] ;
rep(i,1,n) b[i] = b[i-1] + a[i] ;
int ans = 0 ;// ma
// b[i]-ma = ma
LL ma = 0 ;
rep(i,1,n){
ma = max(ma,a[i]) ;
if(ma*2==b[i]) ans ++ ;
}
cout << ans << endl;
}
D
因为所有点都是关于中心点对称分布的,直接求横坐标,纵坐标的平均数就是答案了
inline void solve(){
int n ,m ; cin >> n >> m ;
vector<vector<char>> a(n+1,vector<char>(m+1)) ;
vector<PII> b ;
rep(i,1,n)
rep(j,1,m){
cin >> a[i][j] ;
if(a[i][j]=='#') b.pb({i,j}) ;
}
int sz = b.size() ;
int xx , yy ;
if(sz==1){
xx = b[0].x ; yy = b[0].y ;
cout << xx << " " << yy << endl ;
return ;
}
LL xs = 0 , ys = 0 ;
for(auto& bc : b){
int xc = bc.x , yc = bc.y ;
xs += xc ;
ys += yc ;
}
xx = xs / sz ;
yy = ys / sz ;
cout << xx << " " << yy << endl ;
}
E
直接暴力即可,遍历其中两条边,复杂度(2000^2) ;
对于每个满足条件的长宽高i,j,k(也就是i*j*k==s),在S中的移动范围分别是[i,x],[j,y],[k,z];
然后相乘即可;
inline void solve(){
LL x , y , z , s ; cin >> x >> y >> z >> s ;
LL ans = 0 ;
rpL(i,1,x){
rpL(j,1,y){
LL k = s / (i*j) ;
if(s%(i*j)==0 && k<=z){
LL res = (x-i+1)*(y-j+1)*(z-k+1) ;
ans = max(ans,res) ;
}
}
}
cout << ans << endl;
}
F
一个非常明显的二分答案,但是用堆也可以做;
(可能这场题多的原因);
#include<bits/stdc++.h>
#define IOS ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
using namespace std;
typedef long long LL;
typedef unsigned long long ULL ;
#define PI acos(-1)
#define endl '\n'
#define PII pair<int,int>
#define x first
#define y second
#define no do { cout << "No" << endl; return; } while(0)
#define yes do { cout << "Yes" << endl; return; } while (0)
#define lowbit(x) ((x) & -(x))
#define rep(i, s, e) for (int i=(s);i<=(e);++i)
#define all(v) v.begin(), v.end()
#define pb push_back
const LL INF = 1e18 ;
const int mod = 1e9+7;
const int N = 2e5+10;
int dx[4] = {0, 1, 0, -1}, dy[5] = {1, 0, -1, 0};
LL gcd(LL a, LL b) {
return b ? gcd(b, a % b) : a;
}
LL qmi(int m, int k, int p){
int res = 1 % p, t = m;
while (k){
if (k&1) res = res * t % p;
t = t * t % p;
k >>= 1;
}
return res;
}
int h , n ;
int a[N] , c[N] ;
bool pd(LL m){
LL dmg = 0 ;
rep(i,1,n){
dmg += a[i] * ((m+c[i]-1) / c[i]) ;
if(dmg>=h) return true ;
}
return dmg>=h ;
}
inline void solve(){
cin >> h >> n ;
LL sum = 0 ;
rep(i,1,n) cin >> a[i] , sum += a[i];
rep(i,1,n) cin >> c[i] ;
if(sum>=h){
cout << 1 << endl ;
return ;
}
LL l = 1 , r = 2e12 ;
while(l+1<r){
LL m = (l+r)>>1 ;
if(pd(m)) r = m ;
else l = m ;
// cout << l << endl ;
}
cout << r << endl ;
}
signed main(){
IOS
int _ = 1;
cin >> _;
while(_ --) solve();
return 0;
}
G
- D(n) : 表示数位和;
- D(k*n) = k*D(n) : 那么n的所有数位上的数x在*k之后不能够进位
- --> 能够推出x<=[9/k] ps : []代表下取整
- 然后计算[10^l,10^r)中有多少个数n满足这个条件
- 对于每一个数位,有t=[9/k]+1 种选择,有r个数位,res=t^r
- ans = t^r-t^l
用快速幂优化一下 :
#include<bits/stdc++.h>
#define IOS ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
using namespace std;
typedef long long LL;
typedef unsigned long long ULL ;
#define PI acos(-1)
#define endl '\n'
#define PII pair<int,int>
#define x first
#define y second
#define no do { cout << "No" << endl; return; } while(0)
#define yes do { cout << "Yes" << endl; return; } while (0)
#define lowbit(x) ((x) & -(x))
#define rep(i, s, e) for (int i=(s);i<=(e);++i)
#define all(v) v.begin(), v.end()
#define pb push_back
const LL INF = 1e18 ;
const int Mod = 1e9+7;
const int N = 2e5+10;
int dx[4] = {0, 1, 0, -1}, dy[5] = {1, 0, -1, 0};
LL gcd(LL a, LL b) {
return b ? gcd(b, a % b) : a;
}
LL qmi(LL m, LL k, LL p){
LL res = 1 % p, t = m;
while (k){
if (k&1) res = res * t % p;
t = t * t % p;
k >>= 1;
}
return res;
}
inline void solve(){
// D(n) : 表示数位和
// D(k*n) = k*D(n) : 那么n的所有数位上的数x在*k之后不能够进位
// --> 能够推出x<=[9/k] ps : []代表下取整
// 然后计算[10^l,10^r)中有多少个数n满足这个条件
// 对于每一个数位,有t=[9/k]+1 种选择,有r个数位,res=t^r
// ans = t^r-t^l
LL l , r , k ; cin >> l >> r >> k ;
if(k>=10){
cout << 0 << endl ;
return ;
}
int p = floor(1.0*9/k)+1 ;
LL ans = (qmi(p,r,Mod) - qmi(p,l,Mod)) % Mod ;
if(ans<0) ans += Mod ;
cout << ans << endl ;
}
signed main(){
IOS
int _ = 1;
cin >> _;
while(_ --) solve();
return 0;
}
H
用并查集记录关于每个点的连通块 ;
然后遍历每一行,每一列来求将这一行/列全改为#,之后的连通块的大小,找到最大的;
#include<bits/stdc++.h>
#define IOS ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
using namespace std;
typedef long long LL;
typedef unsigned long long ULL ;
#define PI acos(-1)
#define endl '\n'
#define PII pair<int,int>
#define no do { cout << "No" << endl; return; } while(0)
#define yes do { cout << "Yes" << endl; return; } while (0)
#define lowbit(x) ((x) & -(x))
#define rep(i, s, e) for (int i=(s);i<=(e);++i)
#define all(v) v.begin(), v.end()
#define pb push_back
const LL INF = 1e18 ;
const int mod = 1e9+7;
const int N = 2e5+10;
int dx[4] = {0, 1, 0, -1}, dy[5] = {1, 0, -1, 0};
LL gcd(LL a, LL b) {
return b ? gcd(b, a % b) : a;
}
LL qmi(int m, int k, int p){
int res = 1 % p, t = m;
while (k){
if (k&1) res = res * t % p;
t = t * t % p;
k >>= 1;
}
return res;
}
struct DSU {
std::vector<int> f, siz;
DSU() {}
DSU(int n) {
init(n);
}
void init(int n) {
f.resize(n);
std::iota(f.begin(), f.end(), 0);
siz.assign(n, 1);
}
int find(int x) {
while (x != f[x]) {
x = f[x] = f[f[x]];
}
return x;
}
bool same(int x, int y) {
return find(x) == find(y);
}
bool merge(int x, int y) {
x = find(x);
y = find(y);
if(x == y) return false;
siz[x] += siz[y];
f[y] = x;
return true;
}
int size(int x) {
return siz[find(x)];
}
};
inline void solve(){
int n ,m ; cin >> n >> m ;
vector<string> s(n) ;
rep(i,0,n-1) cin >> s[i] ;
int sz = n * m ;
DSU dsu(sz) ;
rep(i,0,n-1){
rep(j,0,m-1){
if(i+1<n&&s[i][j]=='#'&&s[i+1][j]=='#'){//对行进行扩展
dsu.merge(i*m+j,(i+1)*m+j);//合并
}
if(j+1<m&&s[i][j]=='#'&&s[i][j+1]=='#'){
dsu.merge(i*m+j,i*m+j+1);//合并
}
}
}
int ans = 0 ;
vector<int> vis(sz,-1) ;
rep(r,0,n-1){
int res = 0 ;
rep(i,0,m-1){//修改一行
if(s[r][i]=='.') res ++ ;//修改成#的数目
for(int xx=max(0,r-1);xx<=min(n-1,r+1);xx++){//找上下两行的联通块
if(s[xx][i]=='#'){
int u=dsu.find(xx*m+i);
if(vis[u]!=r){
vis[u] = r ;
res += dsu.size(u);
}
}
}
}
ans = max(ans,res) ;
}
vis.assign(sz,-1) ;
for(int c=0;c<m;c++){
int res = 0 ;
for(int i=0;i<n;i++){
if(s[i][c]=='.') res++ ;
for(int y=max(0,c-1);y<=min(m-1,c+1);y++){
if(s[i][y]=='#'){
int u = dsu.find(i*m+y);
if(vis[u]!=c){
vis[u] = c ;
res += dsu.size(u) ;
}
}
}
}
ans = max(ans,res) ;
}
cout << ans << endl ;
}
signed main(){
IOS
int _ = 1;
cin >> _;
while(_ --) solve();
return 0;
}