其实哪里需要模拟啊!!!这么简单的问题!!!是头猪也想得到
#include <bits/stdc++.h> using namespace std; const int maxn=505; int main() { int n,l,r; cin>>n>>l>>r; if(l/n==r/n) cout<<r%n; else cout<<n-1<<endl; return 0; }
其实也是直接模拟就可以,每次都记录一下改变之后每个数字的位置信息
#include <bits/stdc++.h> using namespace std; const int maxn=8005; int t[maxn]; struct node{ int pre,id; }op[maxn]; int n,q; bool cmp(node a,node b){ if(a.pre!=b.pre) return a.pre<b.pre; else return a.id<b.id; } int main() { cin>>n>>q; for(int i=1;i<=n;i++) { cin>>op[i].pre; op[i].id=i; } sort(op+1,op+1+n,cmp); //先记录排完序后每个点的位置 for(int i=1;i<=n;i++){ t[op[i].id]=i; } while(q--){ int opa,x,v; cin>>opa; if(opa==1){ cin>>x>>v; op[t[x]].pre=v; //然后往两个方向扫描,因为不确定是变小了,还是变大了 for(int j=n;j>=2;j--){ if(cmp(op[j],op[j-1])) swap(op[j],op[j-1]); } for(int j=2;j<=n;j++){ if(cmp(op[j],op[j-1])) swap(op[j],op[j-1]); } //然后更新 for(int i=1;i<=n;i++) t[op[i].id]=i; } else { cin>>x; cout<<t[x]<<endl; } } return 0; }
1、就是字符串的处理,记住可以用sscanf(),sprintf()函数
int t=sscanf(s,"%d.%d.%d.%d:%d",&a,&b,&c,&d,&e); t记录的是成功读取的个数,肯定要等于5,然后判断abcde的大小范围,然后判断是否合格,就是用abcde去构造一个字符串,判断与输入的是否一样即可。sprintf(s2,"%d.%d.%d.%d:%d",a,b,c,d,e);
2、判重直接用map<string,int>即可
#include <bits/stdc++.h> using namespace std; const int maxn=8005; map<string,int> vis; //判重 int n; bool check(char s[]){ int a=-1,b=-1,c=-1,d=-1,e=-1; int t=sscanf(s,"%d.%d.%d.%d:%d",&a,&b,&c,&d,&e); if(t!=5) return 0; if(a<0||a>255) return 0; if(b<0||b>255) return 0; if(c<0||c>255) return 0; if(d<0||d>255) return 0; if(e<0||e>65535) return 0; char s2[35]; sprintf(s2,"%d.%d.%d.%d:%d",a,b,c,d,e); int len=strlen(s); for(int i=0;i<len;i++){ if(s[i]!=s2[i]) return 0; } return 1; } int main() { int n; cin>>n; for(int i=1;i<=n;i++){ char op[105],ad[1005]; cin>>op>>ad; if(op[0]=='S'){ if(!check(ad)) cout<<"ERR"<<endl; else if(vis.count(ad)) cout<<"FAIL"<<endl; else { cout<<"OK"<<endl;vis[ad]=i; } } else{ if(!check(ad)) cout<<"ERR"<<endl; else if(vis.count(ad)) cout<<vis[ad]<<endl; else cout<<"FAIL"<<endl; } } return 0; }
这个其实基础算法,解决方法很多种,其实重点就是怎么处理“合并”的块,然后更新后重新去取数
1、首先对输入的数组先分块,输出每个块的第一个(记录哪个才是第一个),然后因为可能把一个块取完了,这里就直接continue,没取完就更新这个块里面那个才是第一。
2、每一轮取完了之后,要判断会不会有块能够结合,所以再创建一个队列,存放更新完的(合并后的),然后再次放到上面那个队列里面去
#include <bits/stdc++.h> using namespace std; const int maxn=2e5+10; //很多种做法,直接写最好理解的队列,记住要维护每个队列的开始、结束位置,每次减少一个位置 //在每次出每个块的第一个元素的时候,记得两个块在队列里相邻且元素相同,就可以直接合并。 //-->两个队列 struct node{ int st,ed,num; }; bool vis[maxn];//判断有没有出队 int n,cnt; int t[maxn]; //记录输入的数组 queue<node> q,q2; int main() { scanf("%d",&n); for(int i=1;i<=n;i++){ scanf("%d",&t[i]); } t[n+1]=!t[n]; int si=1; for(int i=2;i<=n+1;i++){ if(t[i]!=t[i-1]) { q.push((node){si,i-1,t[i-1]}); si=i; } } cnt=n; //两个队列,一个先出去处理后放q2,然后又更新回q里 while(cnt){ while(q.size()){ node f=q.front(); q.pop(); while(vis[f.st]&&f.st<=f.ed) f.st++; if(f.st>f.ed) continue; printf("%d ",f.st); // vis[f.st]=1; cnt--; if(f.st==f.ed) continue; f.st++; q2.push(f); } printf("\n"); while(q2.size()){ node f=q2.front(); q2.pop(); while(q2.size()){ node nex=q2.front(); if(f.num==nex.num){ f.ed=nex.ed; q2.pop(); } else break; } q.push(f); //丢回去,每次取完更新完之后又放回去 } } return 0; }