A - Humidifier 1
題目描述
AtCoder 公司辦公室有一個加溼器。當前時間是 \(0\) ,加溼器內沒有水。
你要給加溼器加水 \(N\) 次。第 \(i\) 次加水( \(1 \leq i \leq N\) )發生在時間 \(T_i\) ,您加了 \(V_i\) 升水。保證所有 \(1 \leq i \leq N-1\) 的 \(T_i \le T_{i+1}\) 。
然而,加溼器漏水了,只要裡面有水,單位時間內水量就會減少 \(1\) 升。
求在 \(T_N\) 時加完水後加溼器中剩餘的水量。
思路分析
直接模擬即可。
程式碼
// Problem: A - Humidifier 1
// Contest: AtCoder - Daiwa Securities Co. Ltd. Programming Contest 2024(AtCoder Beginner Contest 383)
// URL: https://atcoder.jp/contests/abc383/tasks/abc383_a
// Memory Limit: 1024 MB
// Time Limit: 2000 ms
#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
//#define int long long
namespace gtx{
// Fast IO
void read(int &x){
x = 0;int h = 1;char tmp;
do{tmp=getchar();if(tmp=='-')h*=-1;}while(!isdigit(tmp));
while(isdigit(tmp)) x*=10,x+=tmp-'0',tmp=getchar();
x*=h;
}
void read(char &x){do{x=getchar();}while(x==' '||x=='\n'||x=='\r');}
void write(char x){putchar(x);}
void write(int x){
if(x<0) putchar('-'),x=-x;int st[200]={0},tot=0;
do{st[++tot]=x%10,x/=10;} while(x);
while(tot){putchar(st[tot--]+'0');}
}
void write(int x,char y){write(x);write(y);}
#ifndef int
void read(long long &x){
x = 0;int h = 1;char tmp;
do{tmp=getchar();if(tmp=='-')h*=-1;}while(!isdigit(tmp));
while(isdigit(tmp)) x*=10,x+=tmp-'0',tmp=getchar();
x*=h;
}
void write(long long x){
if(x<0) putchar('-'),x=-x;int st[200]={0},tot=0;
do{st[++tot]=x%10,x/=10;} while(x);
while(tot){putchar(st[tot--]+'0');}
}
void write(long long x,char y){write(x);write(y);}
#endif
signed main(){
int sum = 0,now = 1;
int n;cin >> n;
for(int i = 1;i<=n;i++){
int t,y;read(t);read(y);
while(now<t){
now++;sum--;
}
sum = max(sum,0);
sum += y;
}
write(sum);
return 0;
}
}
signed main(){
// freopen(".in","r",stdin);
// freopen(".out","w",stdout);
// ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
int T = 1;
// gtx::read(T);
while(T--) gtx::main();
return 0;
}
B - Humidifier 2
題目描述
AtCoder 公司辦公室可以表示為由 \(H\) 行和 \(W\) 列組成的網格。讓 \((i, j)\) 表示從上往下第 \(i\) 行和從左往上第 \(j\) 列的單元格。
每個單元格的狀態由一個字元 \(S_{i,j}\) 表示。如果 \(S_{i,j}\) 是 #
,則該單元格包含一張桌子;如果 \(S_{i,j}\) 是 .
,則該單元格是一層樓。可以保證至少有兩個樓層單元格。
您將選擇兩個不同的樓層單元格,並在每個單元格中放置一個加溼器。
放置加溼器後,當且僅當一個單元格 \((i,j)\) 與至少一個加溼器單元格 \((i',j')\) 的曼哈頓距離 \(D\) 在內時,該單元格才被加溼。 \((i,j)\) 和 \((i',j')\) 之間的曼哈頓距離定義為 \(|i - i'| + |j - j'|\) 。需要注意的是,任何放置了加溼器的樓層單元總是加溼的。
求加溼樓層單元的最大可能數目。
思路分析
暴力列舉兩個加溼器的位置,直接模擬即可。
時間複雜度:\(O(n^6)\)
程式碼
// Problem: B - Humidifier 2
// Contest: AtCoder - Daiwa Securities Co. Ltd. Programming Contest 2024(AtCoder Beginner Contest 383)
// URL: https://atcoder.jp/contests/abc383/tasks/abc383_b
// Memory Limit: 1024 MB
// Time Limit: 2000 ms
#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
//#define int long long
namespace gtx{
// Fast IO
void read(int &x){
x = 0;int h = 1;char tmp;
do{tmp=getchar();if(tmp=='-')h*=-1;}while(!isdigit(tmp));
while(isdigit(tmp)) x*=10,x+=tmp-'0',tmp=getchar();
x*=h;
}
void read(char &x){do{x=getchar();}while(x==' '||x=='\n'||x=='\r');}
void write(char x){putchar(x);}
void write(int x){
if(x<0) putchar('-'),x=-x;int st[200]={0},tot=0;
do{st[++tot]=x%10,x/=10;} while(x);
while(tot){putchar(st[tot--]+'0');}
}
void write(int x,char y){write(x);write(y);}
#ifndef int
void read(long long &x){
x = 0;int h = 1;char tmp;
do{tmp=getchar();if(tmp=='-')h*=-1;}while(!isdigit(tmp));
while(isdigit(tmp)) x*=10,x+=tmp-'0',tmp=getchar();
x*=h;
}
void write(long long x){
if(x<0) putchar('-'),x=-x;int st[200]={0},tot=0;
do{st[++tot]=x%10,x/=10;} while(x);
while(tot){putchar(st[tot--]+'0');}
}
void write(long long x,char y){write(x);write(y);}
#endif
const int MAXN = 12;
char a[MAXN][MAXN];int n,m,d;
signed main(){
read(n);read(m);read(d);
for(int i = 1;i<=n;i++){
scanf("%s",a[i]+1);
}
int ans = 0;
for(int i = 1;i<=n;i++){
for(int j = 1;j<=m;j++){
for(int x = 1;x<=n;x++){
for(int y = 1;y<=m;y++){
if(x==i&&y==j) continue;
if(a[i][j]=='#') continue;
if(a[x][y]=='#') continue;
int cnt =0 ;
for(int u1 = 1;u1<=n;u1++){
for(int u2 = 1;u2<=m;u2++){
if(a[u1][u2]=='#') continue;
if(abs(u1-i)+abs(u2-j)<=d){
cnt++;
}else if(abs(u1-x)+abs(u2-y)<=d){
cnt++;
}
}
}
ans = max(ans,cnt);
}
}
}
}
write(ans);
return 0;
}
}
signed main(){
// freopen(".in","r",stdin);
// freopen(".out","w",stdout);
// ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
int T = 1;
// gtx::read(T);
while(T--) gtx::main();
return 0;
}
C - Humidifier 3
題目描述
AtCoder 公司的辦公室是由 \(H\) 行和 \(W\) 列組成的網格。讓 \((i, j)\) 表示從上往下第 \(i\) 行和從左往上第 \(j\) 列的單元格。
每個單元格的狀態由一個字元 \(S_{i,j}\) 表示。如果 \(S_{i,j}\) 為 "#",則該單元格為牆壁;如果 \(S_{i,j}\) 為".",則該單元格為地板;如果 \(S_{i,j}\) 為 "H",則該單元格的地板上放置了加溼器。
如果從至少一個加溼器單元格向上、向下、向左或向右移動最多 \(D\) 次而不經過牆壁,則該單元格被視為加溼單元格。需要注意的是,任何有加溼器的單元格總是加溼的。
求加溼地板單元格的數量。
思路分析
小丑題。
直接將每一個加溼器放進bfs的佇列裡面。
如果一個點出現過兩次,那麼前面出現的那一次的次數一定要多於後一次出現的次數,所以相同的不進去,直接 BFS 即可。
程式碼
// Problem: B - Humidifier 2
// Contest: AtCoder - Daiwa Securities Co. Ltd. Programming Contest 2024(AtCoder Beginner Contest 383)
// URL: https://atcoder.jp/contests/abc383/tasks/abc383_b
// Memory Limit: 1024 MB
// Time Limit: 2000 ms
#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
//#define int long long
namespace gtx{
// Fast IO
void read(int &x){
x = 0;int h = 1;char tmp;
do{tmp=getchar();if(tmp=='-')h*=-1;}while(!isdigit(tmp));
while(isdigit(tmp)) x*=10,x+=tmp-'0',tmp=getchar();
x*=h;
}
void read(char &x){do{x=getchar();}while(x==' '||x=='\n'||x=='\r');}
void write(char x){putchar(x);}
void write(int x){
if(x<0) putchar('-'),x=-x;int st[200]={0},tot=0;
do{st[++tot]=x%10,x/=10;} while(x);
while(tot){putchar(st[tot--]+'0');}
}
void write(int x,char y){write(x);write(y);}
#ifndef int
void read(long long &x){
x = 0;int h = 1;char tmp;
do{tmp=getchar();if(tmp=='-')h*=-1;}while(!isdigit(tmp));
while(isdigit(tmp)) x*=10,x+=tmp-'0',tmp=getchar();
x*=h;
}
void write(long long x){
if(x<0) putchar('-'),x=-x;int st[200]={0},tot=0;
do{st[++tot]=x%10,x/=10;} while(x);
while(tot){putchar(st[tot--]+'0');}
}
void write(long long x,char y){write(x);write(y);}
#endif
const int MAXN = 1000+20;
char a[MAXN][MAXN];int n,m,d;
int h[MAXN][MAXN],s[MAXN][MAXN];
int left[MAXN][MAXN],right[MAXN][MAXN],up[MAXN][MAXN],down[MAXN][MAXN];
int vis[MAXN][MAXN],ans;
queue<pair<pair<int,int>,int>> q;
void add(int x,int y,int s){
if(!(~s)) return;
if(x<1||x>n) return;
if(y<1||y>m) return;
if(a[x][y]=='#') return;
if(vis[x][y]) return;
vis[x][y] = 1;ans++;
// cout << x<< " " << y << endl;
q.push({{x,y},s});
}
signed main(){
read(n);read(m);read(d);
for(int i = 1;i<=n;i++){
scanf("%s",a[i]+1);
}
for(int i = 1;i<=n;i++){
for(int j = 1;j<=m;j++){
if(a[i][j]=='H') add(i,j,d);
}
}
while(!q.empty()){
auto tmp = q.front();
q.pop();
add(tmp.first.first-1,tmp.first.second,tmp.second-1);
add(tmp.first.first+1,tmp.first.second,tmp.second-1);
add(tmp.first.first,tmp.first.second-1,tmp.second-1);
add(tmp.first.first,tmp.first.second+1,tmp.second-1);
}
write(ans);
return 0;
}
}
signed main(){
// freopen(".in","r",stdin);
// freopen(".out","w",stdout);
// ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
int T = 1;
// gtx::read(T);
while(T--) gtx::main();
return 0;
}
D - 9 Divisors
題目描述
求恰好有 \(9\) 個正因數的不大於 \(N\) 的正整數的個數。
思路分析
首先這個題目要讀懂(要看原文才知道翻譯的時候把正因數翻譯成為了正整數)
考慮哪些整數有 9 個因數。
如果做過 BS 期中考試卷的話我們知道完全平方數的因數個數有奇數個。
考慮一個完全平方數 \(n=a^2\)。對於所有 \(a\) 的因數 \(i\),都會有 \(\displaystyle\frac{n}{i}\neq i\),且\(\displaystyle\frac{n}{i}\in \N^+\)
程式碼