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


------------------

posted on 2013-09-09 12:43  电子幼体  阅读(151)  评论(0编辑  收藏  举报

导航