P6971
题意&思路简述
长宽高分别为
每两层交替摆放,即呈“井”字形加高,共
面对几何体的一个棱边,按从近到远令每次的
现在依次给出
求在第几次操作时会使得几何体倒塌?
由此可见,本题操作并不复杂,且有顺序性。
直接开始大模拟。
解题思路
对每次操作判断最顶上
重心可简单的视作是前
其中,由于层次的摆放一次交替呈井字形 。故如果对奇数层移除一块长方体,偶数层应特殊处理。
AC代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
int n, w, h, m;
bool flr[2][2501][10001];
int lft[2][2501], rgt[2][2501];
int cet[2][2501], num[2][2501];
int cmp(double x) {
if(abs(x) < 1e-8) return 0;
return x > 0 ? 1 : -1;
}
bool jug(double center, double left, double right) {
if(cmp(center - left) <= 0 || cmp(center - right) >= 0)
return false;
return true;
}
int main(){
scanf("%d %d %d %d", &n, &w, &h, &m);
memset(flr, true, sizeof(flr));
long long lmt = (1+n) * n / 2;
for(int i=1;i<=h;i++){
cet[i%2][(i+1)/2] = lmt;
num[i%2][(i+1)/2] = n;
lft[i%2][(i+1)/2] = 1;
rgt[i%2][(i+1)/2] = n;
}
for(int idx=1, l, k;idx<=m;idx++){
scanf("%d %d", &l, &k);
bool flg = l % 2;
l = (l+1)/2;
flr[flg][l][k] = 0;
cet[flg][l] -= k;
num[flg][l]--;
for(int i=1;i<=n;i++)
if(flr[flg][l][i] == true) {
lft[flg][l] = i;
break;
}
for(int i=n;i;i--)
if(flr[flg][l][i] == true) {
rgt[flg][l] = i;
break;
}
double tCet = 0, tNum = 0;
for(int i=h;i;i--){
if(cmp(tNum) == 1 && flg == i%2) {
double center = tCet * 1.0 / tNum;
if(jug(center, lft[flg][(i+1)/2] - 0.5, rgt[flg][(i+1)/2] + 0.5) == false) {
printf("yes\n%d\n", idx);
return 0;
}
}
if(i%2 == flg)
tCet += cet[flg][(i+1)/2],
tNum += num[flg][(i+1)/2];
else
tCet += num[!flg][(i+1)/2] * (1.0+n)/2.0,
tNum += num[!flg][(i+1)/2];
}
}
printf("no\n");
}