------------------
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;
}
------------------