哎。。本来想写完之后在写博客的,但感觉剩下两道比较难啊,估计要等好久才能写出来了。。
A-Card Stacking
题目链接:https://ac.nowcoder.com/acm/contest/993/A
题目大意:n头牛坐在一圈,按顺序发牌。1,2,3,4,5.。。问自己最后都获得那些牌,从小到大输出自己活得的牌。
思路:简单deque模拟就好了,最后排一下序。
ACCode:
#include<stdio.h>
#include<math.h>
#include<string.h>
#include<stdlib.h>
#include<time.h>
// srand(unsigned)time(NULL));rand();
#include<map>
#include<set>
#include<deque>
#include<queue>
#include<stack>
#include<string>
#include<fstream>
#include<iostream>
#include<algorithm>
#define ll long long
#define Pair pair<int,int>
#define clean(a,b) memset(a,b,sizeof(a))
using namespace std;
const int MAXN=1e5+10;
const int INF32=0x3f3f3f3f;
const ll INF64=0x3f3f3f3f3f3f3f3f;
const ll MOD=1e9+7;
const double PI=acos(-1.0);
const double EPS=1.0e-8;
//unsigned register
// ios::sync_with_stdio(false)
deque<int> deq;
int Ans[MAXN];
int n,k,p;
int main(){
scanf("%d%d%d",&n,&k,&p);
for(int i=1;i<=k;++i) deq.push_back(i);
int peo=2,tmp=0;
while(deq.size()){
if(peo==1) Ans[++tmp]=deq.front();
deq.pop_front();
for(int i=1;i<=p;++i){
deq.push_back(deq.front());deq.pop_front();
}
peo=peo%n+1;
}sort(Ans+1,Ans+tmp+1);
for(int i=1;i<=tmp;++i) printf("%d\n",Ans[i]);
}
B-Bookshelf
题目链接:https://ac.nowcoder.com/acm/contest/993/B
题目大意:一个书架高S,每头牛高Hi,n头牛,问最低多高能够超过书架
思路:文少写的,排一下序加起来就好了
ACCode:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
int main(){
ll n,b;
scanf("%lld%lld",&n,&b);
ll a[n+3];
for(int i=0;i<n;i++){
scanf("%lld",&a[i]);
}
sort(a,a+n);
ll sum=0;
int f=0;
for(int i=n-1;i>=0;i--){
sum=sum+a[i] ;
f++;
if(sum>=b){
break;
}
}
printf("%d\n",f);
return 0;
}
C-Bookshelf 2
题目链接:https://ac.nowcoder.com/acm/contest/993/C
题目大意:还是上道题的意思,问最低的超过S的高度。
思路:数据太小,直接暴力DFS就好了
ACCode:
int A[25];
int n,H;
int DFS(int Sum,int i){
//cout<<Sum<<" "<<i<<endl;
if(Sum>=H) return Sum-H;
if(i==n+1) return INF32;
return min(DFS(Sum+A[i],i+1),DFS(Sum,i+1));
}
int Solve(){
return DFS(0,1);
}
int main(){
scanf("%d%d",&n,&H);
for(int i=1;i<=n;++i) scanf("%d",&A[i]);
printf("%d\n",Solve());
}
D-迷路的牛
题目链接:https://ac.nowcoder.com/acm/contest/993/D
题目大意:中文题,比较容易读懂。
思路:最大的就是找到最大的距离,每次只移动挨着。最小移动1次或2次。注意如果一开始就是挨着的都是0.
ACCode:
int main(){
int a,b,c;scanf("%d%d%d",&a,&b,&c);
int Max=max(abs(a-b),abs(b-c))-1,Min=min(abs(a-b),abs(b-c))-1;
if(Max==0&&Min==0) printf("0\n0\n");
else printf("%d\n%d\n",Min==1?1:2,Max);
}
E-对牛排序
题目链接:https://ac.nowcoder.com/acm/contest/993/E
题目大意:中文题
思路:神仙写的,类似于找逆序数。
ACCode:
#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
int main()
{
int n;
cin>>n;
int arr[110];
for(int i=1;i<=n;i++)
{
cin>>arr[i];
}
int ans=arr[1];
int flag=1;
for(int i=2;i<=n;i++)
{
if(ans>arr[i])
{
//cout<<ans<<" "<<arr[i]<<endl;
ans=arr[i];
flag=i;
}
else
ans=arr[i];
}
cout<<flag-1<<endl;
return 0;
}
F-Mud Puddles
题目链接:https://ac.nowcoder.com/acm/contest/993/F
题目大意:给出一些点不能通过,牛只能上下左右走。问最少多少步走到终点。
思路:数据范围较小,暴力BFS即可。
ACCode:
const int MAXN=1e3+10;
const int INF32=0x3f3f3f3f;
const ll INF64=0x3f3f3f3f3f3f3f3f;
const ll MOD=1e9+7;
const double PI=acos(-1.0);
const double EPS=1.0e-8;
//unsigned register
// ios::sync_with_stdio(false)
struct Point{
int i,j,size;
Point(int _i=0,int _j=0,int _size=0){
i=_i;j=_j;size=_size;
}
};
int MP[MAXN][MAXN];
int Vis[MAXN][MAXN];
int Fi[5]={0,0,0,1,-1},Fj[5]={0,1,-1,0,0};
Point End;
int n;
int BFS(Point Str){
clean(Vis,INF32);Vis[Str.i][Str.j]=0;
queue<Point> que;que.push(Str);
while(que.size()){
Point u=que.front();que.pop();
if(u.i==End.i&&u.j==End.j) return u.size;
for(int i=1;i<=4;++i){
Point v=Point(u.i+Fi[i],u.j+Fj[i],u.size+1);
if(MP[v.i][v.j]==0&&Vis[v.i][v.j]==INF32){
que.push(v);Vis[v.i][v.j]=v.size;
}
}
}return -1;
}
int main(){
scanf("%d%d%d",&End.i,&End.j,&n);
End.i+=500;End.j+=500;
for(int i=1;i<=n;++i){
int x,y;scanf("%d%d",&x,&y);
x+=500;y+=500;
MP[x][y]=1;
}printf("%d\n",BFS(Point(500,500,0)));
}
H-Charm Bracelet
题目链接:https://ac.nowcoder.com/acm/contest/993/H
题目大意:n个物品,每个物品有权值和重量两个属性,找到约束重量的最大权值组合。
思路:简单背包,文少秒A。
ACCode:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
struct node
{
int wi,di;
};
int main(){
ll n,m;
scanf("%lld%lld",&n,&m);
node a[n+3];
for(int i=0;i<n;i++){
scanf("%d%d",&a[i].wi,&a[i].di);
}
ll b[m+3];
memset(b,0,sizeof(b));
ll mx=0;
for(int i=0;i<n;i++){
for(int j=m;j>=a[i].wi;j--){
b[j]=b[j]<b[j-a[i].wi]+a[i].di?b[j-a[i].wi]+a[i].di:b[j];
mx=mx<b[j]?b[j]:mx ;
}
}
printf("%lld\n",mx);
return 0;
}
J-Sightseeing Cows
题目链接:https://ac.nowcoder.com/acm/contest/993/J
题目大意:给出一个有向图,每个节点有一个权值val,每条边有一个长度len。奶牛要逛不少于两个点,并且最后要回到原点。求Ans= 所逛过的节点权值之和 / 经过的边的距离之和 的最大Ans。
思路:最优比率环原题:https://blog.csdn.net/qq_40482358/article/details/96325343
ACCode:
#include<stdlib.h>
#include<string.h>
#include<stdio.h>
#include<time.h>
#include<math.h>
// srand(unsigned)time(NULL));rand();
#include<map>
#include<set>
#include<deque>
#include<queue>
#include<stack>
#include<bitset>
#include<string>
#include<fstream>
#include<iostream>
#include<algorithm>
#define ll long long
#define Pair pair<double,double>
#define clean(a,b) memset(a,b,sizeof(a))
using namespace std;
const int MAXN=5e3+10;
const int INF32=0x3f3f3f3f;
const ll INF64=0x3f3f3f3f3f3f3f3f;
const ll MOD=1e9+7;
const double PI=acos(-1.0);
const double EPS=1.0e-8;
//unsigned register
// ios::sync_with_stdio(false)
struct Node{
int v,nxt;
double len;
Node(int _v=0,double _len=0,int _nxt=0){
v=_v;len=_len;nxt=_nxt;
}
};
Node Edge[MAXN];
int Head[MAXN],Ecnt;
int Stk[MAXN],tot;
double Val[MAXN],Dis[MAXN];
int Vis[MAXN],Cnt[MAXN];
int n,m;
void Intt(){
clean(Head,-1);Ecnt=0;
}
void AddEdge(int a,int b,double val){
Edge[Ecnt]=Node(b,val,Head[a]);
Head[a]=Ecnt++;
}
int Judge(double mid){
for(int i=1;i<=n;++i){
Dis[i]=0;Vis[i]=1;Cnt[i]=1;
Stk[tot++]=i;
}
while(tot){
int u=Stk[--tot];Vis[u]=0;
for(int i=Head[u];i+1;i=Edge[i].nxt){
int v=Edge[i].v;
double temp=Edge[i].len*mid-Val[v];
if(Dis[v]>Dis[u]+temp){
Dis[v]=Dis[u]+temp;
if(Vis[v]==0){
Vis[v]=1;Cnt[v]++;
Stk[tot++]=v;
if(Cnt[v]>n) return 1;
}
}
}
}return 0;
}
int main(){
Intt();
scanf("%d%d",&n,&m);
for(int i=1;i<=n;++i){
scanf("%lf",&Val[i]);
}
for(int i=1;i<=m;++i){
double a,b,c;scanf("%lf%lf%lf",&a,&b,&c);
AddEdge(a,b,c);
}
double l=0.0,r=1000.0,mid;
while(l<r-EPS){
mid=(l+r)/2.0;
if(Judge(mid)) l=mid;
else r=mid;
}printf("%.2f\n",r);
}
K-Gourmet Grazers
题目链接:https://ac.nowcoder.com/acm/contest/993/K
题目大意:给出n头牛,每头牛有两个属性:金钱,美味。m个产品,每个产品有两个属性:金钱,美味。只有一个产品的两个属性都大于等于牛的时候,这头牛才会去吃这个产品。问使n头牛都能吃上产品,最少花费多少。如果不能满足,输出-1;
思路:贪心+Splay。原题:https://blog.csdn.net/qq_40482358/article/details/96132929
ACCode:
#include<stdio.h>
#include<math.h>
#include<string.h>
#include<stdlib.h>
#include<time.h>
// srand(unsigned)time(NULL));rand();
#include<map>
#include<set>
#include<deque>
#include<queue>
#include<stack>
#include<string>
#include<fstream>
#include<iostream>
#include<algorithm>
#define ll long long
#define Pair pair<int,int>
#define clean(a,b) memset(a,b,sizeof(a))
using namespace std;
const int MAXN=1e5+10;
const int INF32=0x3f3f3f3f;
const ll INF64=0x3f3f3f3f3f3f3f3f;
const ll MOD=1e9+7;
const double PI=acos(-1.0);
const double EPS=1.0e-8;
//unsigned register
// ios::sync_with_stdio(false)
class SplayTree{
struct Node{
ll A,B;
int l,r,f,siz;
Node(ll _A=0,ll _B=0,int _l=0,int _r=0,int _f=0,int _siz=0){
A=_A;B=_B;l=_l;r=_r;f=_f;siz=_siz;
}
friend int operator < (Node a,Node b){
if(a.A==b.A) return a.B<b.B;
return a.A<b.A;
}
};
Node Tree[MAXN];
int Lazy[MAXN];
int Rt,Ecnt;//Rt的父节点是0,第一个节点从1开始。
void PushUp(int x){//次序
Tree[x].siz=Tree[Tree[x].l].siz+Tree[Tree[x].r].siz+1;
}
void PushDown(int x){//反转
if(Lazy[x]){
int temp=Tree[x].l;Tree[x].l=Tree[x].r;Tree[x].r=temp;
Lazy[Tree[x].l]^=1;Lazy[Tree[x].r]^=1;
Lazy[x]=0;
}
}
void Rotate(int x,int oper){
int y=Tree[x].f;
PushDown(y);PushDown(x);
if(oper){
Tree[y].r=Tree[x].l;
if(Tree[x].l!=0) Tree[Tree[x].l].f=y;
Tree[x].l=y;
}
else{
Tree[y].l=Tree[x].r;
if(Tree[x].r!=0) Tree[Tree[x].r].f=y;
Tree[x].r=y;
}Tree[x].f=Tree[y].f;
if(Tree[y].f){
if(y==Tree[Tree[y].f].l) Tree[Tree[y].f].l=x;
else Tree[Tree[y].f].r=x;
}Tree[y].f=x;PushUp(y);
}
void Splay(int x,int f){
PushDown(x);
int y=Tree[x].f,z=0;
while(y!=f){
z=Tree[y].f;
PushDown(z);PushDown(y);PushDown(x);
if(z==f) Rotate(x,x==Tree[y].r);
else{
if((x==Tree[y].l^y==Tree[z].l)==0){
Rotate(y,y==Tree[z].r);Rotate(x,x==Tree[y].r);
}
else{
Rotate(x,x==Tree[y].r);Rotate(x,x==Tree[z].r);
}
}PushUp(x);y=Tree[x].f;
}PushUp(x);
if(f==0) Rt=x;
}
int MinNode(ll Key){
int x=Rt,ans=-1;
PushDown(x);
while(1){
if(Tree[x].A>=Key){//该节点可以取得
ans=x;
if(Tree[x].l) x=Tree[x].l;//向左子节点
else return ans;
}
else{//不可以取得
if(Tree[x].r) x=Tree[x].r;//可以的话直接向右走了
else return ans;//没有符合要求的
}
}
}
int GetPre(){
int x=Rt;
if(Tree[x].l) x=Tree[x].l;
else return x;
while(1){
if(Tree[x].r) x=Tree[x].r;
else return x;
}
}
public:
void Intt(){
clean(Lazy,0);
Rt=0;Ecnt=0;
}
void Insert(ll A,ll B){
Tree[++Ecnt]=Node(A,B,0,0,0,1);
int y=0,x=Rt;
while(x){
y=x;
if(Tree[Ecnt]<Tree[x]) x=Tree[x].l;
else if(Tree[x]<Tree[Ecnt]) x=Tree[x].r;
else return ;
}
if(y==0) Rt=Ecnt;
else if(Tree[Ecnt]<Tree[y]){
Tree[y].l=Ecnt;Tree[Ecnt].f=y;
}
else{
Tree[y].r=Ecnt;Tree[Ecnt].f=y;
}Splay(Ecnt,0);
}
ll DeleteMin(ll Key){//所有的B都符合要求,找到最小的A>=P
int Pos=MinNode(Key);
if(Pos==-1) return -1;
ll Ans=Tree[Pos].A;
Splay(Pos,0);
//cout<<"Pos,Pre:"<<Pos<<" "<<GetPre()<<endl;
Splay(GetPre(),0);//cout<<"Debug:\n";Show(Rt);cout<<"End\n";
if(Pos==GetPre()){
Rt=Tree[Rt].r;Tree[Rt].f=0;
}
else{
Splay(Pos,Rt);
Tree[Rt].r=Tree[Pos].r;Tree[Tree[Rt].r].f=Rt;
}
return Ans;
}
//-------
int GetRt(){
return Rt;
}
void Show(int x){
if(x==0) return ;
PushDown(x);
printf("x:%d xf:%d xl:%d xr:%d (A,B)(%lld,%lld)\n",x,Tree[x].f,Tree[x].l,Tree[x].r,Tree[x].A,Tree[x].B);
Show(Tree[x].l);
// printf("A:%lld B:%lld\n",Tree[x].A,Tree[x].B);
Show(Tree[x].r);
}
};
struct Node{
ll P,G;
Node(ll _P=0,ll _G=0){
P=_P;G=_G;
}
friend int operator < (Node a,Node b){
if(a.G==b.G) return a.P<b.P;
return a.G<b.G;
}
};
SplayTree Spl;
Node Cows[MAXN],Goods[MAXN];
int n,m;
int PosX(ll Key,int l,int r){
while(l<=r){
int mid=(l+r)>>1;
if(Goods[mid].G<Key) l=mid+1;
else r=mid-1;
}return l;
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;++i) scanf("%lld%lld",&Cows[i].P,&Cows[i].G);
for(int i=1;i<=m;++i) scanf("%lld%lld",&Goods[i].P,&Goods[i].G);
sort(Cows+1,Cows+1+n);sort(Goods+1,Goods+1+m);
ll ans=0;int flag=1,tmp=m;
Spl.Intt();
for(int i=n;i>=1;--i){
int Pos=PosX(Cows[i].G,1,tmp);
//printf("P:%lld G:%lld tmp:%d Pos:%d\n",Cows[i].P,Cows[i].G,tmp,Pos);
for(int j=Pos;j<=tmp;++j) Spl.Insert(Goods[j].P,Goods[j].G);
//cout<<"--"<<endl;Spl.Show(Spl.GetRt());cout<<"--"<<endl;
ll temp=Spl.DeleteMin(Cows[i].P);
if(temp==-1){//找最小的花费
flag=0;break;
}
ans+=temp;tmp=Pos-1;
//cout<<"ans:"<<ans<<endl;
}
if(flag==0) printf("-1\n");
else printf("%lld\n",ans);
}
L-Best Cow Line
题目链接:https://ac.nowcoder.com/acm/contest/993/L
题目大意:n个大写字符进行重新排位。只能从头或者尾取出一个放在新的字符串的尾。找出字典序最小的那个串
思路:碰见取小的,如果一样DFS进去比较,找出第一个小的即可。注意输出80个字符就要换行。。眼瞎看不见WA了无数发
ACCode:
#include<stdio.h>
#include<math.h>
#include<string.h>
#include<stdlib.h>
#include<time.h>
// srand(unsigned)time(NULL));rand();
#include<map>
#include<set>
#include<deque>
#include<queue>
#include<stack>
#include<string>
#include<fstream>
#include<iostream>
#include<algorithm>
#define ll long long
#define Pair pair<int,int>
#define clean(a,b) memset(a,b,sizeof(a))
using namespace std;
const int MAXN=5e5+10;
const int INF32=0x3f3f3f3f;
const ll INF64=0x3f3f3f3f3f3f3f3f;
const ll MOD=1e9+7;
const double PI=acos(-1.0);
const double EPS=1.0e-8;
//unsigned register
// ios::sync_with_stdio(false);
char S[MAXN];
int Id[MAXN];
int n;
int DFS(int top,int bot){
if(S[top]==S[bot]){
if(top==bot) return 1;
else if(top==bot-1) return 1;
return DFS(top+1,bot-1);
}
else if(S[top]<S[bot]) return 1;
else return 0;
}
int main(){
ios::sync_with_stdio(false);
cin>>n;
for(int i=1;i<=n;++i){
char ch;cin>>ch;S[i]=ch;
}
int top=1,bot=n,i=1;
while(top<bot){
if(S[top]==S[bot]){
if(DFS(top+1,bot-1)){//top较大
Id[top]=i;
++i;++top;
}
else{
Id[bot]=i;
++i;--bot;
}
}
else if(S[top]<S[bot]){
Id[top]=i;
++i;++top;
}
else{
Id[bot]=i;
++i;--bot;
}
}
Id[bot]=n;
top=1,bot=n;
for(int i=1;i<=n;++i){
// printf("top=%d,%d bot=%d,%d\n",top,Id[top],bot,Id[bot]);
if(Id[top]==i){
cout<<S[top];++top;
//printf("%c",S[top]);++top;
}
else{
cout<<S[bot];--bot;
//printf("%c",S[bot]);--bot;
}
if(i%80==0) cout<<"\n";
}
}