

其实哪里需要模拟啊!!!这么简单的问题!!!是头猪也想得到
#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;
}
posted on
浙公网安备 33010602011771号