A. Maximum Element In A Stack
求出一个出栈入栈序列中,每一次操作进行完成后,栈内最大的元素。
首先我们维护两个栈,一个栈保存最大值,一个栈正常操作。我们只维护一个最大值的栈的情况就可以了。
进栈:如果当前进栈的值大于等于最大值栈顶的值,其他值就不管了
出栈:如果当前出栈的元素等于最大值栈的元素,那么最大值栈也要出栈。否则的话就不管了
这样下来,最大值栈的栈顶元素就是我们想要的最大值。
正确性的相关证明就留给读者了
#include <bits/stdc++.h>
#include<cstring>
#define ll long long
using namespace std;
const int MAXN = 5e6 + 5;
ll st[MAXN],sst[MAXN];
int n, p, q, m;
unsigned int SA, SB, SC;
unsigned int rng61()
{
SA ^= SA << 16;
SA ^= SA >> 5;
SA ^= SA << 1;
unsigned int t = SA;
SA = SB;
SB = SC;
SC ^= t ^ SA;
return SC;
}
void gen(int cat)
{
scanf("%d%d%d%d%u%u%u", &n, &p, &q, &m, &SA, &SB, &SC);
ll ans = 0LL;
int tp1 = 0,tp2 = 0;
for(int i = 1; i <= n; i++)
{
if(rng61() % (p + q) < p)
{
//PUSH(rng61() % m + 1);
ll now = 1LL*(rng61() % m + 1);
//cout<<"push:"<<now<<endl;
st[++tp1] = now;
if(sst[tp2] <= now)
{
sst[++tp2] = now;
}
}
else
{
//POP();
// cout<<"pop"<<endl;
if(tp2 > 0&& st[tp1] == sst[tp2])
{
tp2--;
}
if(tp1 > 0)
tp1--;
}
//cout<<i<<": "<<sst[tp2]<<endl;
if(tp1 && tp2) ans ^= (1LL*i*sst[tp2]);
}
printf("Case #%d: %lld\n",cat,ans);
}
void check()
{
ll ans = 0;
int tp1 = 0,tp2 = 0;
cin>>n;
for(int i = 1; i <= n; i++)
{
int op ;
cin>>op;
if(op != -1)
{
//PUSH(rng61() % m + 1);
int now = op;
//cout<<"push:"<<now<<endl;
st[++tp1] = now;
if(sst[tp2] <= now)
{
sst[++tp2] = now;
}
}
else
{
//POP();
// cout<<"pop"<<endl;
if(tp2 > 0 && st[tp1] >= sst[tp2])
{
tp2--;
}
if(tp1 > 0)
tp1--;
}
cout<<i<<": "<<sst[tp2]<<endl;
//ans ^= (1LL*i*sst[tp2]);
}
}
int main()
{
int ca,cat = 1;
scanf("%d",&ca);
while(ca--)
{
memset(st,0,sizeof(st));
memset(sst,0,sizeof(sst));
gen(cat++);
//check();
}
return 0;
}
B. Rolling The Polygon
强行用余弦定理算出每次翻转的角度,然后计算一下圆弧长就行
#include <bits/stdc++.h>
#include<cstring>
using namespace std;
const double pi=acos(-1.0);
struct node{
double x,y;
}z[150];
int n;
double x11,y11;
double solve(int t){
double a=(z[t].x-z[(t-1+n)%n].x)*(z[t].x-z[(t-1+n)%n].x)+(z[t].y-z[(t-1+n)%n].y)*(z[t].y-z[(t-1+n)%n].y);
double b=(z[t].x-z[(t+1+n)%n].x)*(z[t].x-z[(t+1+n)%n].x)+(z[t].y-z[(t+1+n)%n].y)*(z[t].y-z[(t+1+n)%n].y);
double c=(z[(t-1+n)%n].x-z[(t+1+n)%n].x)*(z[(t-1+n)%n].x-z[(t+1+n)%n].x)+(z[(t-1+n)%n].y-z[(t+1+n)%n].y)*(z[(t-1+n)%n].y-z[(t+1+n)%n].y);
double ans=(a+b-c)/(2*sqrt(a)*sqrt(b));
ans=acos(ans);
double num=sqrt((x11-z[t].x)*(x11-z[t].x)+(y11-z[t].y)*(y11-z[t].y));
return num*(pi-ans);
}
int main()
{
int t;
cin>>t;
cout<<fixed<<setprecision(3);
for(int ca=1;ca<=t;ca++){
cin>>n;
for(int i=0;i<n;i++){
cin>>z[i].x>>z[i].y;
}
cin>>x11>>y11;
double sum=0;
for(int i=0;i<n;i++){
sum+=solve(i);
}
cout<<"Case #"<<ca<<": "<<sum<<endl;
}
return 0;
}
C. Caesar Cipher
很水的模拟
D. Take Your Seat
题意是编号为1的人随机坐在一个座位上,如果照编号顺序上飞机的人发现自己的座位被占了,该乘客就会随机选一个座位,问最后一个上飞机的人坐在自己座位正确位置上的概率是多少?
这是第一问,第二问上飞机的顺序也是随机的,同样求最后一个上飞机的人坐在自己位置上的概率。
我们先考虑的一个问题,如果只有一个人的话,概率是1,如果有两个人的话,说明第一个人做回了自己的座位,这个概率就是0.5,我们强行找一波规律,发现都是1/2……
问题2只要先列出来各种情况,同样找规律就ok
H. Fight Against Monsters
简单贪心,预处理杀死每个怪物的次数,选择(ATK/次数)最高的怪物优先杀死,可以证明一定是及最优的
F. Moving On 题
题意就是最短路,要求每次询问最短路的时候经过的点上的权值不超过一个值。
首先只有50个点,肯定是floyd算法,想到Floyd的dp思想,我们尝试加一维上去,设dp[i][j][k] 为从i到j,压力值都再前k小的路径上的最小值。
我们把枚举第k小的时候,相当于还是判断了走第k小的那个中继点的最优性。
也就是dp[i][j][k] = min(dp[i][j][k-1] ,dp[i][kk][k-1] + dp[kk][j][k-1])
意思是走或者不走,都会将前k-1小的值向上更新,这里需要保存原来这些点的位置。
#include <bits/stdc++.h>
#define ll long long
#define pb push_back
using namespace std;
const int MAXN = 201;
const int INF = 0x3f3f3f3f;
int w[MAXN],ww[MAXN];
int dp[MAXN][MAXN][MAXN];
int id[MAXN];
int main()
{
int ca,cat = 1;
scanf("%d",&ca);
while(ca--)
{
int n,q;
scanf("%d%d",&n,&q);
int u,v,d;
for(int i = 1;i<=n;i++) {
scanf("%d",&w[i]);
id[i] = i;
}
sort(id+1,id+n+1,[&](int x,int y)
{
return w[x] < w[y];
});
sort(w+1,w+n+1);
memset(dp,INF,sizeof(dp));
for(int i = 1;i<=n;i++)
{
for(int j = 1;j<=n;j++)
{
scanf("%d",&dp[i][j][0]);
}
}
for(int k = 1;k<=n;k++)
{
int kk = id[k];
for(int i = 1;i<=n;i++)
{
for(int j = 1;j<=n;j++)
{
dp[i][j][k] = min(dp[i][j][k-1],dp[i][kk][k-1]+dp[kk][j][k-1]);
}
}
}
printf("Case #%d:\n",cat++);
while(q--)
{
int u,v,d;
scanf("%d%d%d",&u,&v,&d);
int t;
for(t = 1;t<=n;t++)
{
if(w[t] > d)
{
break;
}
}
printf("%d\n",dp[u][v][t-1]);
}
}
return 0;
}