1、玩具谜题
算法思路:模拟
估分:100;
实得:100;
代码:
#include<bits/stdc++.h>
using namespace std;
const int N=100005;
int n,m,di[N],a[N],s[N];
string na[N];
int main(){
cin>>n>>m;
for(int i=1;i<=n;i++)
cin>>di[i]>>na[i];
for(int i=1;i<=m;i++)
cin>>a[i]>>s[i];
int t=1;
for(int i=1;i<=m;i++){
if( (a[i]==0&&di[t]==0) || (a[i]==1&&di[t]==1) ){
if(t>s[i]){
t=t-s[i];
continue;
}
if(t<=s[i])
t=t+n-s[i];
continue;
}
if( (a[i]==0&&di[t]==1) || (a[i]==1&&di[t]==0) ){
t=t+s[i];
if(t>n)
t=t-n;
continue;
}
}
cout<<na[t]<<endl;
return 0;
}
2、神奇的幻方
算法思路:模拟
估分:100
实得:100
代码:
#include<bits/stdc++.h>
using namespace std;
const int N=50;
int a[N][N],n;
struct shu{
int h,l;
}s[N*N];
int main(){
cin>>n;
a[1][n/2+1]=1;
s[1].h=1;
s[1].l=n/2+1;
for(int k=2;k<=n*n;k++){
if(s[k-1].h==1&&s[k-1].l!=n){
s[k].h=n;
s[k].l=s[k-1].l+1;
a[s[k].h][s[k].l]=k;
}
if(s[k-1].h!=1&&s[k-1].l==n){
s[k].h=s[k-1].h-1;
s[k].l=1;
a[s[k].h][s[k].l]=k;
}
if(s[k-1].h==1&&s[k-1].l==n){
s[k].h=s[k-1].h+1;
s[k].l=s[k-1].l;
a[s[k].h][s[k].l]=k;
}
if(s[k-1].h!=1&&s[k-1].l!=n){
if(a[s[k-1].h-1][s[k-1].l+1]==0&&s[k-1].h-1>0&&s[k-1].l+1<=n){
s[k].h=s[k-1].h - 1;
s[k].l=s[k-1].l + 1;
}
else{
s[k].h=s[k-1].h+1;
s[k].l=s[k-1].l;
}
a[s[k].h][s[k].l]=k;
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++)
cout<<a[i][j]<<" ";
cout<<endl;
}
return 0;
}
3、蚯蚓
算法思路:队列or优先队列or二叉堆?可惜我不会这个
估分:0;
实得分数:0;
正解(洛谷):
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e5 + 100;
inline int read(){
int x = 0;char c = getchar();
while(!isdigit(c))c = getchar();
while(isdigit(c))x = x * 10 + c - '0',c = getchar();
return x;
}
queue<ll> Q[4];
int val[maxn],n,m,q,u,v,t;
ll delta;
inline int findmax(){
int res = 0;
for(int i = 1;i <= 3;i++)
if(!Q[i].empty() && (!res || Q[i].front() > Q[res].front()))res = i;
return res;
}
inline ll cut(ll x){return 1ll * u * x / v;}
inline void solve(int tim){
ll x = Q[findmax()].front();Q[findmax()].pop();
if(tim % t == 0)printf("%lld ",x + delta);
Q[2].push(cut(x + delta) - delta - q);Q[3].push(x - cut(x + delta) - q);
delta += q;
}
int main(){
n = read(),m = read(),q = read(),u = read(),v = read(),t = read();
for(int i = 1;i <= n;i++)val[i] = read();
sort(val + 1,val + 1 + n);
for(int i = n;i >= 1;i--)Q[1].push(val[i]);
for(int i = 1;i <= m;i++)solve(i);
putchar('\n');
for(int i = 1;i * t <= n + m;i++){
for(int j = 1;j <= t - 1;j++)
Q[findmax()].pop();
printf("%lld ",Q[findmax()].front() + delta);
Q[findmax()].pop();
}
putchar('\n');
return 0;
}
4、列队
算法思路:暴力先拿前六组得分 线段树、平衡树、树状数组----啥都不会
估分:30;
实得:30;
我的暴力代码:
#include<bits/stdc++.h>
using namespace std;
int n,m,p,x[10001],y[10001],a[10010][10010],t;
int main(){
cin>>n>>m>>p;
for(int i=1;i<=p;i++)
cin>>x[i]>>y[i];
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
a[i][j]=(i-1)*m+j;
for(int i=1;i<=p;i++){
cout<<a[x[i]][y[i]]<<endl;
t=a[x[i]][y[i]];
for(int j=y[i];j<m;j++)a[x[i]][j]=a[x[i]][j+1];
for(int j=x[i];j<n;j++)a[j][m]=a[j+1][m];
a[n][m]=t;
}
return 0;
}
正解(洛谷):
#include <bits/stdc++.h>
#define ll long long
using namespace std;
int n,m,q,x,y,pos,tot,lim,rt[300005],ls[12000005],rs[12000005],sm[12000005];vector<ll>v[300005];
int que(int x,int l,int r,int v)
{
if(l==r) return l;
int mid=(l+r)>>1,tmp=mid-l+1-sm[ls[x]];
if(v<=tmp) return que(ls[x],l,mid,v);
return que(rs[x],mid+1,r,v-tmp);
}
void upd(int &x,int l,int r,int p)
{
if(!x) x=++tot;sm[x]++;
if(l==r) return;int mid=(l+r)>>1;
if(p<=mid) upd(ls[x],l,mid,p);
else upd(rs[x],mid+1,r,p);
}
ll wk1(int x,ll y)
{
pos=que(rt[n+1],1,lim,x);upd(rt[n+1],1,lim,pos);
ll ans=pos<=n?1ll*pos*m:v[n+1][pos-n-1];
return v[n+1].push_back(y?y:ans),ans;
}
ll wk2(int x,int y)
{
pos=que(rt[x],1,lim,y);upd(rt[x],1,lim,pos);
ll ans=pos<m?1ll*(x-1)*m+pos:v[x][pos-m];
return v[x].push_back(wk1(x,ans)),ans;
}
int main()
{
scanf("%d%d%d",&n,&m,&q);lim=max(n,m)+q;
for(;q--;printf("%lld\n",y==m?wk1(x,0):wk2(x,y))) scanf("%d%d",&x,&y);
}
反思
知识点上有好多好多盲区以及不熟练的地方,还得多加学习、练习