20250818 OI 总结
T2
前言:输出样例都给了贪心的方法了
正确思路:贪心,枚举,能还钱就还钱。
死因:贪心出错了(我的思路就是能还钱就还钱,但返回走下去)
代码:
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
#define int int
const int MAXN = 1e5 + 7;
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + 7;
int n;
int fuzhai_cnt = 0,shouyi_cnt = 0,pos,ans;
int a[MAXN];
signed main() {
scanf("%d",&n);
for(int i = 1;i <= n;i++)
scanf("%d",&a[i]);
for(int i = 1;i <= n;i++){
if(a[i] < 0){
if(!pos){
pos = i;
}
fuzhai_cnt += a[i];
}else{
shouyi_cnt += a[i];
if(shouyi_cnt >= (-(fuzhai_cnt)) && fuzhai_cnt != 0){
shouyi_cnt += fuzhai_cnt;
fuzhai_cnt = 0;
ans += (i - pos) * 2;
// cout << (i - pos) * 2 << endl;
pos = 0;
}
}
// cout << pos << endl;
}
printf("%d\n",ans+n);
return 0;
}
T3
前言:类似题目(看起来好像是类似的) 嗅探器
死因:没清空
正确思路:dfs 即可
正解:
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
#define int int
const int MAXN = 1e5 + 7;
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + 7;
vector<int>e[MAXN];
int n,m;
int vis[MAXN],dis[MAXN];
void dfs(int x,int j){
vis[x] = 1;
for(auto y : e[x]){
if(!vis[y]){
if(y != j){
dis[y] = dis[x] + 1;
dfs(y,j);
}
}
}
vis[x] = 0;
}
int main(){
scanf("%d%d",&n,&m);
for(int i = 1;i <= m;i++){
int x,y;
scanf("%d%d",&x,&y);
e[x].push_back(y);
e[y].push_back(x);
}
int s,t;
int ans = 0;
scanf("%d%d",&s,&t);
for(int j = 1;j <= n;j++){
memset(dis,-1,sizeof(dis));
dfs(s,j);
if(dis[t] == -1) ans++;
}
printf("%d\n",ans - 1);
return 0;
}
歪解:
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
#define int int
const int MAXN = 1e5 + 7;
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + 7;
vector<int>e[MAXN];
int n,m;
int s,t,ans;
int dfn[MAXN],low[MAXN],times;
void tarjan(int u,int fa){
low[u] = dfn[u] = ++times;
bool flag = false;
int son_ans = 0;
for(auto v : e[u]){
if(dfn[v]){
low[u] = min(low[u],dfn[v]);
}else{
son_ans++;
tarjan(v,u);
low[u] = min(low[v],low[u]);
if(!flag && fa != u && low[v] >= dfn[u] && dfn[t] >= dfn[v]){
flag = 1;
ans++;
}
}
}
}
int main(){
scanf("%d%d",&n,&m);
for(int i = 1;i <= m;i++){
int x,y;
scanf("%d%d",&x,&y);
e[x].push_back(y);
e[y].push_back(x);
}
scanf("%d%d",&s,&t);
tarjan(s,s);
printf("%d\n",ans);
return 0;
}
总结:下次一定记得清空(已经抄了60次了)
T4
思路:找到循环节,每一个进行模拟即可(细节有一点多,还在调)
T5
思路:看 \(n\) 只有 6, \(dfs\) 启动(看上下左右的最小值求面积取一个 max)。
还在调试代码:
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
#define int int
const int MAXN = 6 + 7;
const double INF = 1e9;
const int mod = 1e9 + 7;
const double PI = 3.1415926;
int n;
double sx,sy,ex,ey;
double x[MAXN],y[MAXN];
double dist[MAXN][MAXN],r[MAXN];
bool vis[MAXN];
double orz_dist(int i,int j){
double res1 = (x[i] - x[j]) * (x[i] - x[j]);
double res2 = (y[i] - y[j]) * (y[i] - y[j]);
return sqrt(res1+res2);
}
double step = 0;
void dfs(int cur,double sum){
if(cur > n){
step = max(step,sum);
return;
}
for(int i = 1;i <= n;i++){
if(vis[i]) continue;
double Rmin = INF;
Rmin = min({abs(x[i]-ex),abs(sx-x[i]),abs(sy-y[i]),abs(ey-y[i])});
for(int j = 1;j <= n;j++){
if(!vis[j] || i == j) continue;
Rmin = min(Rmin,max(0.0,dist[i][j]-r[j]));
}
vis[i] = 1;
r[i] = Rmin;
dfs(cur+1,sum + PI * r[i] * r[i]);
vis[i] = 0;
r[i] = 0;
}
}
int main(){
scanf("%d",&n);
scanf("%lf%lf%lf%lf",&sx,&sy,&ex,&ey);
if(sx > ex) swap(sx,sy),swap(ex,ey);
if(sy > ey) swap(ex,ey);
for(int i = 1;i <= n;i++)
scanf("%lf%lf",&x[i],&y[i]);
for(int i = 1;i <= n;i++)
for(int j = 1;j <= n;j++)
dist[i][j] = orz_dist(i,j);
dfs(1,0.0);
step = abs(sx-ex)*abs(sy-ey)-step;
printf("%.0f\n",step);
return 0;
}