牛客第二场7.19
K题
https://ac.nowcoder.com/acm/contest/11253/K
首先给了两个b[i]数组
第一步,补全
2 2 5 4
| b[value] | 0 | 2 | 0 | 0 | 4 |
|---|---|---|---|---|---|
| 下标 | 1 | 2 | 3 | 4 | 5 |
补完之后如下,方法就是stack中放一个较大的数必然会数值加一,并且保证合理
| b[value] | 1 | 2 | 3 | 4 | 4 |
|---|---|---|---|---|---|
| 下标 | 1 | 2 | 3 | 4 | 5 |
然后画出一个折线图,第一次出现的数字一定会上升,比如第一次出现2,3,4. 第二次出现的会比第一次出现的数值的位置有所下降。
最后如图:

要怎么做呢?
申请一个数组d[],初始化为 d[i]=i*n;
每次取过对应的位置之后就让d[i]-1就会邦正下次重复的数字取得数值比上次的小。
最后通过数值排序即可得到合法顺序。
这是才用的思维题的方式解决的。正确解法应用单调栈(待学)
具体代码如下:
#include <bits/stdc++.h>
#define inf 0x7fffffff
#define ll long long
#define int long long
//#define double long double
//#define double long long
#define re int
//#define void inline void
#define eps 1e-8
//#define mod 1e9+7
#define ls(p) p<<1
#define rs(p) p<<1|1
#define pi acos(-1.0)
#define pb push_back
#define mk make_pair
#define P pair < int , int >
using namespace std;
const int mod=1e9+7;
//const int inf=1e18;
const int MA=1e18;
const int NN=1e6+5;//??????.???? 4e8
const int MI=-1e18;
struct node{
int x,y;
}N[1000005];
int B[1000005];
int n,k;
int now[1000005];
int y[1000005];
int d[1000005];
int ans[1000005];
int last[NN];
int b[NN],c[NN],a[NN],top;
bool cmp(node a,node b)
{
if(a.y!=b.y) return a.y<b.y;
return a.x>b.x;
}
void solve()
{
cin>>n>>k;
for(int i=0;i<=n;i++)d[i]=-1;
for(int i=1;i<=k;i++)
{
int a1,a2;
cin>>a1>>a2;
now[a1]=a2;
last[a1]=a2;
}
for(int i=1;i<=n;i++) {
if(now[i]==0) now[i]=now[i-1]+1;
if(i<now[i])
{
cout<<-1<<endl;
return;
}
if(now[i-1]+1<now[i])
{
cout<<-1<<endl;
return;
}
}
for(int i=1;i<=n;i++)d[i]=i*n;
for(int i=1;i<=n;i++)
{
int w=now[i];
y[i]=d[w];
d[w]--;
}
for(int i=1;i<=n;i++)N[i].x=i,N[i].y=y[i];
sort(N+1,N+n+1,cmp);
for(int i=1;i<=n;i++) ans[N[i].x]=i;
for(int i=1;i<=n;i++) cout<<ans[i]<<" ";
}
signed main()
{
ios::sync_with_stdio(false);
solve();
return 0;
}
F题
https://ac.nowcoder.com/acm/contest/11253/F
较为简单
直接求P到A点距离为P到B点距离的K倍,列出空间表达式
化简发现是一个圆。发现圆的坐标以及半径参数都已知。同理P2,C,D;
用得到的x1,y1,z1,r1与x2,y2,z2,r2直接套用两立体圆求体积交的模板即可解决。
具体代码如下:
#include <bits/stdc++.h>
#define inf 0x7fffffff
#define ll long long
#define int long long
//#define double long double
//#define double long long
#define re int
//#define void inline void
#define eps 1e-8
//#define mod 1e9+7
#define ls(p) p<<1
#define rs(p) p<<1|1
#define pi acos(-1.0)
#define pb push_back
#define mk make_pair
#define P pair < int , int >
using namespace std;
const int mod=1e9+7;
//const int inf=1e18;
//const int M=1e8;
//const int N=1e5+5;/????.???? 4e8
int n;
double a[55],b[55],c[55];
void solve()
{
for(int i=1;i<=4;i++) cin>>a[i]>>b[i]>>c[i];
double k1,k2;
cin>>k1>>k2;
double t1=(a[1]-a[2]*k1*k1)/(k1*k1-1);
double t2=(b[1]-b[2]*k1*k1)/(k1*k1-1);
double t3=(c[1]-c[2]*k1*k1)/(k1*k1-1);
double rx1=-t1;
double ry1=-t2;
double rz1=-t3;
double r1=sqrt(t2*t2+t1*t1+t3*t3+(a[1]*a[1]+b[1]*b[1]+c[1]*c[1]-k1*k1*(a[2]*a[2]+b[2]*b[2]+c[2]*c[2]))/(k1*k1-1));
t1=(a[3]-a[4]*k2*k2)/(k2*k2-1);
t2=(b[3]-b[4]*k2*k2)/(k2*k2-1);
t3=(c[3]-c[4]*k2*k2)/(k2*k2-1);
double rx2=-t1;
double ry2=-t2;
double rz2=-t3;
double r2=sqrt(t2*t2+t1*t1+t3*t3+(a[3]*a[3]+b[3]*b[3]+c[3]*c[3]-k2*k2*(a[4]*a[4]+b[4]*b[4]+c[4]*c[4]))/(k2*k2-1));
//以下是求立体交的函数代码。
double dis = sqrt((rx1 - rx2) * (rx1 - rx2) + (ry1 - ry2) * (ry1 - ry2) + (rz1 - rz2) * (rz1 - rz2));
if (dis >= r1 + r2)
{
printf("0.0000000\n");
}
else if (dis <= fabs(r1 - r2))
{
double maxn = min(r1, r2);
double s = 4.0 / 3.0 * pi * (maxn * maxn * maxn);
printf("%.7lf\n", s);
}
else
{
double s = 0;
double h1 = r1 - (r1 * r1 - r2 * r2 + dis * dis) / (2 * dis);
s += (pi * h1 * h1 * (3 * r1 - h1) / 3.0);
double h2 = r2 - (r2 * r2 - r1 * r1 + dis * dis) / (2 * dis);
s += (pi * h2 * h2 * (3 * r2 - h2) / 3.0);
printf("%.7lf\n", s);
}
}
signed main()
{
int T=1;
cin>>T;
for(int index=1;index<=T;index++)
{
solve();
// puts("");
}
return 0;
}
补题:
I题 大模拟题
别骂了别骂了,还没补完呢。
大模拟
吃点经验 双线的图题一定要用四维空间来保存。双队列太容易出错了!
考虑情况要考虑所有可能发生的情况。
#include <iostream>
#include <bits/stdc++.h>
//#define int long long
#define eps 1e-8
using namespace std;
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
char a[25][25];
char b[25][25];
bool d[25][25][25][25];
int dx[]={1,0,0,-1};
int dy[]={0,-1,1,0};
int ex[]={1,0,0,-1};
int ey[]={0,1,-1,0};
char cc[]={'D','L','R','U'};
struct node
{
int x,y;
string s;
}N[25][25],N2[25][25];
void solve()
{
for(int i=1;i<=20;i++)
{
scanf("%s",a[i]+1);
scanf("%s",b[i]+1);
}
queue<node>q1;
queue<node>q2;
node A,B;
A.x=20,A.y=20,B.x=20,B.y=1;
q1.push(A);
q2.push(B);
node ans;
d[A.x][A.y][B.x][B.y] = true;
while(!q1.empty()&&!q2.empty())
{
node n1=q1.front();
node n2=q2.front();
q1.pop();
q2.pop();
// if(d[n1.x][n1.y][n2.x][n2.y])continue;
// d[n1.x][n1.y][n2.x][n2.y]=true;
if(n1.x==1&&n1.y==20&&n2.x==1&&n2.y==1)
{
ans=n1;
break;
}
for(int i=0;i<=3;i++)
{
int lx=n1.x+dx[i];
int ly=n1.y+dy[i];
int rx=n2.x+ex[i];
int ry=n2.y+ey[i];
if(a[lx][ly]!='.')lx=n1.x,ly=n1.y;
if(b[rx][ry]!='.')rx=n2.x,ry=n2.y;
if(d[lx][ly][rx][ry])continue;
q1.push(node{lx,ly,n1.s+cc[i]});
q2.push(node{rx,ry,n1.s+cc[i]});
d[lx][ly][rx][ry] = true;
}
}
cout<<ans.s.size()<<endl<<ans.s<<endl;
int x1=20,y1=20,x2=20,y2=1;
a[20][20]='A',b[20][1]='A';
for(int i=0;i<ans.s.size();i++)
{
if(ans.s[i]=='D')
{
x1++;
x2++;
if(a[x1][y1]!='.'&&a[x1][y1]!='A')x1--;
if(b[x2][y2]!='.'&&b[x2][y2]!='A')x2--;
a[x1][y1]='A',b[x2][y2]='A';
}
if(ans.s[i]=='U')
{
x1--;
x2--;
if(a[x1][y1]!='.'&&a[x1][y1]!='A')x1++;
if(b[x2][y2]!='.'&&b[x2][y2]!='A')x2++;
a[x1][y1]='A',b[x2][y2]='A';
}
if(ans.s[i]=='L')
{
y1--;
y2++;
if(a[x1][y1]!='.'&&a[x1][y1]!='A')y1++;
if(b[x2][y2]!='.'&&b[x2][y2]!='A')y2--;
a[x1][y1]='A',b[x2][y2]='A';
}
if(ans.s[i]=='R')
{
y1++;
y2--;
if(a[x1][y1]!='.'&&a[x1][y1]!='A')y1--;
if(b[x2][y2]!='.'&&b[x2][y2]!='A')y2++;
a[x1][y1]='A',b[x2][y2]='A';
}
}
for(int i=1;i<=20;i++)
{
cout<<a[i]+1<<" "<<b[i]+1<<endl;
}
}
int main(int argc, char** argv) {
// ios::sync_with_stdio(false);
// std::cin.tie(nullptr);
solve();
return 0;
}
这篇博客探讨了如何利用单调栈解决数位上升序列的问题,以及如何计算两个立体圆的体积交集。对于数位上升序列,通过初始化数组并调整每个位置的值,可以构造出合法的序列。对于立体圆的交集,通过空间表达式求解,可以得出交集的体积。博主提供了详细的代码实现和解题思路。

813

被折叠的 条评论
为什么被折叠?



