还能回到原先吗 绞尽脑汁翻阅文献 这名为爱的实验 被等号连接
test40
教练模拟器真好玩 /kel
俄罗斯方块
旋转一下然后计数,注意对对称图形去重喵。
#pragma GCC optimize(1,2,3,"Ofast","inline")
#include<bits/stdc++.h>
#define int long long
#define up(i,l,r) for(int i=l; i<=r; ++i)
#define dn(i,r,l) for(int i=r; i>=l; --i)
using namespace std;
const int N=15;
int n, m, A, B, C, D, E;
char str[N][N];
signed main() {
ios::sync_with_stdio(0);
cin.tie(0);
cin >> n >> m;
up(i,1,n) cin >> (str[i]+1);
up(i,1,n) up(j,1,m) if(str[i][j]!='.') {
char v=str[i][j];
if(v==str[i+1][j]&&v==str[i][j+1]&&v==str[i+1][j+1]) ++A;
if(v==str[i][j+1]&&v==str[i][j+2]&&v==str[i][j+3]) ++B;
if(v==str[i+1][j]&&v==str[i+2][j]&&v==str[i+3][j]) ++B;
if(v==str[i+1][j]&&v==str[i][j+1]&&v==str[i+1][j-1]) ++C;
if(v==str[i][j+1]&&v==str[i-1][j]&&v==str[i+1][j+1]) ++C;
if(v==str[i][j-1]&&v==str[i+1][j]&&v==str[i+1][j+1]) ++D;
if(v==str[i][j+1]&&v==str[i-1][j+1]&&v==str[i+1][j]) ++D;
if(v==str[i-1][j]&&v==str[i][j-1]&&v==str[i][j+1]) ++E;
if(v==str[i+1][j]&&v==str[i][j-1]&&v==str[i][j+1]) ++E;
if(v==str[i-1][j]&&v==str[i+1][j]&&v==str[i][j-1]) ++E;
if(v==str[i-1][j]&&v==str[i+1][j]&&v==str[i][j+1]) ++E;
}
cout << A << '\n' << B << '\n' << C << '\n' << D << '\n' << E << '\n';
return 0;
}
矩形染色
顺着单调栈扫扫就行。
#pragma GCC optimize(1,2,3,"Ofast","inline")
#include<bits/stdc++.h>
#define int long long
#define up(i,l,r) for(int i=l; i<=r; ++i)
#define dn(i,r,l) for(int i=r; i>=l; --i)
#define pii pair<int,int>
#define mp make_pair
#define fir first
#define sec second
using namespace std;
const int N=1000005;
int n, ans;
pii u[N];
signed main() {
ios::sync_with_stdio(0);
cin.tie(0);
cin >> n;
up(i,1,n) cin >> u[i].fir >> u[i].sec;
up(i,1,n) u[i].fir/=2, u[i].sec/=2;
sort(u+1,u+1+n,[](pii i,pii j){return i.fir>j.fir;});
int lst=u[1].fir, lim=0;
up(i,1,n+1) {
ans+=lim*(lst-u[i].fir);
lim=max(lim,u[i].sec);
lst=u[i].fir;
}
cout << 4*ans << '\n';
return 0;
}
帝国重建
设计一下 \(f_i/g_i\) 表示前缀最优答案和最后的新高度,那么希望最小化 \(f\) 再最小化 \(g\),转移条件只有 \(h_i-h_j>g_j\) 这样,其实有决策单调性但我也没有想过为什么。但是不管怎么说,就那一个条件够做单调队列优化了,可能里面还有一个有效点的单调性。
#pragma GCC optimize(1,2,3,"Ofast","inline")
#include<bits/stdc++.h>
#define int long long
#define up(i,l,r) for(int i=l; i<=r; ++i)
#define dn(i,r,l) for(int i=r; i>=l; --i)
#define pii pair<int,int>
#define mp make_pair
#define fir first
#define sec second
using namespace std;
const int N=1000005;
int n, h[N], f[N], g[N], top=1, p[N], v[N];
signed main() {
ios::sync_with_stdio(0);
cin.tie(0);
cin >> n;
up(i,1,n) cin >> h[i];
up(i,2,n) h[i]+=h[i-1];
up(i,1,n) {
// 从后往前找第一个 h[i]>h[j]+g[j]
// 所以权值在 queue 里面应该是 1 2 3 ... 向上
// dn(j,i-1,0) {
// if(h[i]-h[j]>=g[j]) {
// f[i]=f[j]+i-j-1;
// g[i]=h[i]-h[j];
// break;
// }
// }
int j=p[upper_bound(v+1,v+1+top,h[i])-v-1];
f[i]=f[j]+i-j-1, g[i]=h[i]-h[j];
while(top&&h[i]+g[i]<=v[top]) --top;
p[++top]=i, v[top]=h[i]+g[i];
}
cout << f[n] << '\n';
return 0;
}
树上铲雪
你去想捏 dp,然后发现可以直接往上面贪心,就是那种没有后效性的题目。
#pragma GCC optimize(1,2,3,"Ofast","inline")
#include<bits/stdc++.h>
#define int long long
#define up(i,l,r) for(int i=l; i<=r; ++i)
#define dn(i,r,l) for(int i=r; i>=l; --i)
#define pb push_back
using namespace std;
const int N=200005;
int n, a[N], ans;
vector<int> to[N];
void dfs(int x,int fad) {
int sum=0, mx=0;
for(int y:to[x]) if(y!=fad) {
dfs(y,x);
sum+=a[y];
mx=max(mx,a[y]);
}
if(sum<=a[x]) return;
int k=(mx<=sum-mx?sum/2:sum-mx);
k=min(k,min(sum-a[x],a[x])), ans+=k, a[x]-=k;
if(sum-2*k>a[x]) ans+=sum-2*k-a[x];
}
signed main() {
ios::sync_with_stdio(0);
cin.tie(0);
cin >> n;
up(i,1,n) cin >> a[i];
up(i,2,n) {
int u, v;
cin >> u >> v;
to[u].pb(v);
to[v].pb(u);
}
dfs(1,0);
cout << a[1]+ans << '\n';
return 0;
}

浙公网安备 33010602011771号