第36次ccf-csp题解(思维)

  • 比赛感受

这会刚打完上海icpc,比起区域赛的题,这个简单太多了。
感受还不错,写的很顺手。除了第3题,其他3题都是一发过。
刷题得长期刷。


第36次ccf-csp题解(思维)


 
 

  • A题 移动

题意:f : y+1 ;  b : y-1 ;   l : x-1 ;  r : x+1

 
一个简单的模拟,若当前操作使机器人移出场地,那么使机器人移回来就好

#include <bits/stdc++.h> #define int long long using namespace std; void ooo(int x){     cout<<x<<'n'; } signed main() {     int n, k;cin>>n>>k;     for(int i=1;i<=k;i++){         int x, y;cin>>x>>y;         string s;cin>>s;         int len=s.size();         for(int j=0;j<len;j++){             if(s[j]=='f')y+=1;             else if(s[j]=='b')y-=1;             else if(s[j]=='l')x-=1;             else x+=1;              if(y>n)y--;             if(y<1)y++;             if(x>n)x--;             if(x<1)x++;         }         cout<<x<<' '<<y<<'n';     }     return 0; }  

  • B题 梦境巡查

这个题不算太难,有点思维,对码力要求不高。

  

它假设当bi为0时求初始时要带的最小补给。

关键在于怎样维护bi=0时,全程中所拥有补给的最小量(为负数表示还需要多少补给) 所以就是一个单点修改,以bi为分界处,维护前半段和后半段最小值,对两段最小值取最小值,为负数则取绝对值,为非负数则为0。

   

第36次ccf-csp题解(思维)

#include <bits/stdc++.h> #define int long long using namespace std; const int xmmm=2e5+10; int a[xmmm], b[xmmm]; int c[xmmm]; int sum[xmmm]; int pmi[xmmm], lmi[xmmm]; int ans[xmmm]; void ooo(int x){     cout<<x<<'n'; } signed main() {     int n;cin>>n;     for(int i=0;i<=n;i++){         cin>>a[i];         c[i*2+1]=0-a[i];     }     for(int i=1;i<=n;i++){         cin>>b[i];         c[i*2]=b[i];     }     pmi[0]=lmi[2*n+2]=0-1e10;     for(int i=1;i<=2*n+1;i++){         sum[i]=sum[i-1]+c[i];     }     for(int i=1;i<=2*n+1;i++){         if(i==1)pmi[i]=sum[i];         else pmi[i]=min(pmi[i-1], sum[i]);     }     for(int i=2*n+1;i>=1;i--){         if(i==2*n+1)lmi[i]=sum[i];         else lmi[i]=min(lmi[i+1], sum[i]);     }     for(int i=1;i<=n;i++){         int pos=i*2;         int t1=pmi[pos-1];         int t2=lmi[pos]-b[i];         ans[i]=min(t1, t2);     }     for(int i=1;i<=n;i++){         if(ans[i]<0)cout<<0-ans[i]<<' ';         else cout<<0<<' ';     }     return 0; } /*  3 5 5 5 5 0 100 0  3  9 4 6 2 9 4 6 */  

  • D题 跳房子

这个题感觉还没有C题难。
这其实是一个很简单的图遍历的问题
建完边还是只有一个前驱的这种,简单版的迪杰斯特拉。
处理出b数组,每个点只入队列一次。

第36次ccf-csp题解(思维)

第36次ccf-csp题解(思维)

#include <bits/stdc++.h> //#define int long long using namespace std; void ooo(int x){     cout<<x<<'n'; } struct p{     int id, num; }; const int xmmm=2e5+10; int a[xmmm], b[xmmm], k[xmmm]; int dis[xmmm]; bool vis[xmmm]; signed main() {     int n;cin>>n;     for(int i=1;i<=n;i++){         cin>>a[i];         b[i]=i-a[i];     }     for(int i=1;i<=n;i++)cin>>k[i];     int pos=0;     queue<p>q;     //q.clear();     q.push(p{1, 0});     int ans=-1;     while(!q.empty()){         p t=q.front();q.pop();         if(vis[t.id])continue;         vis[t.id]=1;         if(t.id==n){             ans=t.num;break;         }         int x=t.id;         if(x+k[x]<=pos)continue;         if(x+k[x]>=n){             q.push(p{n, t.num+1});             continue;         }         for(int i=max(pos+1, x+1);i<=min(n, x+k[x]);i++){             q.push(p{b[i], t.num+1});         }         pos=max(pos, x+k[x]);     }     cout<<ans<<'n';     return 0; } /*  5 0 1 2 3 0 3 4 4 10 15  10 0 1 1 1 1 3 1 0 3 0 2 4 5 4 1 4 1 3 5 3 */  

  • C题 缓存模拟


一个大模拟按他的要求来就好了,详细的可以看注释

#include <bits/stdc++.h> #define int long long  using namespace std; const int xxx=3e5; const int xx=7e4; int head[xxx],nnum[xxx];  // m组里有多少个 struct p{     int x, y; }; vector<p>ans; void ooo(int x){     cout<<x<<'n'; }; struct node {     int id, num;     bool operator<(const node &a)const {return a.num<num;} }; priority_queue<node>qq[xx]; unordered_map<int, int>a, vis; // 位置//是否修改 signed main() {      int n, m, q;cin>>n>>m>>q;     for(int i=1;i<=q;i++){         int x, y;cin>>x>>y;         if(a[y]){ / /判断是否命中             int pos=(y / n ) %m;             head[pos]++;             qq[pos].push(node{y, head[pos]});             a[y]=head[pos];             if(x==0)x=x;             else {                 vis[y]=1; //判断是否改写             }         }         else {             int pos=( y / n )%m; //位置             if(nnum[pos]==n){ //如果已经满了                 while(!qq[pos].empty()){                     node tt=qq[pos].top();qq[pos].pop();                     if(a[tt.id]!=tt.num)continue;                     if(vis[tt.id]){                         //cout<<"pos"<<tt.id<<' '<<tt.num<<' '<<a[tt.id]<<'n';                         ans.push_back(p{(int)1, tt.id});                         vis[tt.id]=0;                     }                     head[pos]++;                     a[y]=head[pos];                     if(x)vis[y]=1;                     qq[pos].push(node{y, head[pos]});                     ans.push_back(p{(int)0, y});                     a[tt.id]=0;break;                 }             }             else {                 head[pos]++;                 a[y]=head[pos];                 nnum[pos]++;                 qq[pos].push(node{y, head[pos]});                 if(x)vis[y]=1;                 ans.push_back(p{(int)0, y});             }         }     }     int len=ans.size();     for(int i=0;i<len;i++){         cout<<ans[i].x<<' '<<ans[i].y<<'n';     }     return 0; } /*  4 8 8 0 0 0 1 1 2 0 1 1 0 0 32 1 33 0 34   1 1 3 1 0 1 1 0 2 */  

  • 自我总结

这次写题的顺序是1243,再写一点点。

发表评论

相关文章