Codeforces Round #103 (Div. 2) //缺E
------------------
A. Arrival of the General
---
可以交换相邻两个数字。
求将最大值移到最左边,最小值移到最右边所用的最小步数。
---
#include <iostream> using namespace std; int main() { int n; int a[111]; cin>>n; int mx=0,mi=999; int p1,p2; for (int i=0;i<n;i++){ cin>>a[i]; if (a[i]>mx){ mx=a[i]; p1=i; } if (a[i]<=mi){ mi=a[i]; p2=i; } } int ans=p1+(n-p2-1); if (p1>p2) ans--; cout<<ans<<endl; return 0; }
------------------
B. Meeting
---
矩形x1y1x2y2的边上坐着人。有n个火炉(x,y,r),火炉能温暖欧几里得距离小于等于r的人。
求有多少人冷。
注意矩形可能为一个点。
---
#include <iostream> using namespace std; struct Warm{ int x,y,r; }a[1111]; int n; int x1,y1,x2,y2; bool cold(int x,int y){ for (int i=0;i<n;i++){ if ( (x-a[i].x)*(x-a[i].x)+(y-a[i].y)*(y-a[i].y)<=a[i].r*a[i].r ) return false; } return true; } int main() { int ans=0; cin>>x1>>y1>>x2>>y2; cin>>n; if (x1>x2) swap(x1,x2); if (y1>y2) swap(y1,y2); for (int i=0;i<n;i++){ cin>>a[i].x>>a[i].y>>a[i].r; } for (int i=x1;i<=x2;i++){ if (cold(i,y1)) ans++; if (y1!=y2&&cold(i,y2)) ans++; } for (int i=y1+1;i<=y2-1;i++){ if (cold(x1,i)) ans++; if (x1!=x2&&cold(x2,i)) ans++; } cout<<ans<<endl; return 0; }------------------
C. Anagram Search
---
若一个串改变字符顺序能等于另一个串,则称这个串为另一个串的anagram。
给一个串s,由小写字符与?构成,?能代替任意一个字符。
给一个串p,问s有多少个子串是p的anagram。
分析可知,若要两个串为anagram只要串含有的字符数量相等即可。
考虑s的一个子串[l,r],若其含有的所有字符数都<=串p的字符数。则[l,r+1] [l,r+2] [l,r+...]有可能为p的anagram。
若某一个字符(除了?)数>串p的该字符数。则[l,r+1] [l,r+2] [l,r+...] 以及[l,r]一定不是p的anagram。
对于一个满足以上性质的子串,若该串长度==p的长度,则它是一个anagram。
因此可以线性扫描s,令当前的字符为r,若[l,r]满足性质则l++;
---
#include <iostream> #include <cstring> using namespace std; char p[111111]; int lenp; char s[111111]; int lens; int chr[27]; int match[27]; int gc(char c){ if (c>='a'&&c<='z') return c-'a'; return 26; } int main() { int ans=0; cin>>s>>p; memset(match,0,sizeof(match)); memset(chr,0,sizeof(chr)); lenp=strlen(p); for (int i=0;i<lenp;i++){ match[gc(p[i])]++; } lens=strlen(s); int l=0; int num=0; for (int i=0;i<lens;i++){ chr[gc(s[i])]++; num++; while (l>=0&&l<=i&& ( (s[i]!='?'&&chr[gc(s[i])]>match[gc(s[i])]) || num>lenp )){ chr[gc(s[l])]--; num--; l++; } if (num==lenp) ans++; } cout<<ans<<endl; return 0; }-----------------
D. Missile Silos
---
见 Codeforces 144D. Missile Silos 最短路
已知导弹发射井(?)距离首都s的最短距离为l,求出导弹发射井的数量。
首先求出每个顶点到首都的距离dis[i]。若dis[i]==len则ans++。
然后枚举每条边,进行如下计算:
if ( (dis[u]<len) && (len-dis[u]<w) && (w-(len-dis[u])>len-dis[v]) ) ans++;导弹位于该条边靠近顶点u的位置
if ( (dis[v]<len) && (len-dis[v]<w) && (w-(len-dis[v])>len-dis[u]) ) ans++;导弹位于该条边靠近顶点v的位置
if ( (dis[v]<len) && (dis[u]<len) && (dis[u]+dis[v]+w==len*2) ) ans++;导弹位于顶点u,v之间
最后ans即为导弹数量。。。
---
#include <iostream> #include <cstring> #include <queue> using namespace std; const int OO=1e9+9; const int maxn=222222; const int INF=1e9+7; struct hentai{ int to; int next; int flow; }edges[maxn]; struct death{ int u; int v; int w; }link[maxn]; int cnt; int outque[maxn]; int head[maxn]; int edge; int node,src; int n,m; int dis[maxn]; bool v[maxn]; int len; queue<int>que; void init(int _node,int _src) { node=_node; src=_src; for (int i=0;i<=node;i++) { head[i]=-1; dis[i]=OO; v[i]=false; } edge=0; cnt=0; } void addedge(int u,int v,int w) { edges[edge].flow=w;edges[edge].to=v;edges[edge].next=head[u];head[u]=edge++; edges[edge].flow=w;edges[edge].to=u;edges[edge].next=head[v];head[v]=edge++; link[cnt].u=u;link[cnt].v=v;link[cnt].w=w;cnt++; } bool SPFA() { int top; for (int i=0;i<=node;i++) { dis[i]=INF; } memset(v,0,sizeof(v)); memset(outque,0,sizeof(outque)); while (!que.empty()) que.pop(); que.push(src); v[src]=true; dis[src]=0; while (!que.empty()) { top=que.front(); que.pop(); v[top]=false; outque[top]++; if (outque[top]>node) return false; int k=head[top]; while (k!=-1) { if ( dis[edges[k].to]==INF||dis[edges[k].to]>dis[top]+edges[k].flow ) { dis[edges[k].to]=dis[top]+edges[k].flow; if (!v[edges[k].to]) { v[edges[k].to]=true; que.push(edges[k].to); } } k=edges[k].next; } } return true; } int main() { cin>>n>>m>>src; init(n,src); for (int i=1;i<=m;i++) { int u,v,w; cin>>u>>v>>w; addedge(u,v,w); } cin>>len; //SPFA SPFA(); int ans=0; for (int i=1;i<=node;i++) { if (dis[i]==len) ans++; } //(u,v) int u,v,w; for (int i=0;i<cnt;i++) { u=link[i].u; v=link[i].v; w=link[i].w; if ( (dis[u]<len) && (len-dis[u]<w) && (w-(len-dis[u])>len-dis[v]) ) ans++; if ( (dis[v]<len) && (len-dis[v]<w) && (w-(len-dis[v])>len-dis[u]) ) ans++; if ( (dis[v]<len) && (dis[u]<len) && (dis[u]+dis[v]+w==len*2) ) ans++; } //over cout<<ans<<endl; return 0; }
------------------