其实哪里需要模拟啊!!!这么简单的问题!!!是头猪也想得到
1 2 3 4 5 6 7 8 9 10 11 12 | #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; } |
其实也是直接模拟就可以,每次都记录一下改变之后每个数字的位置信息
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | #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>即可
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | #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、每一轮取完了之后,要判断会不会有块能够结合,所以再创建一个队列,存放更新完的(合并后的),然后再次放到上面那个队列里面去
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | #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; } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 按钮权限的设计及实现