20180718练习赛 [AtCoder]ABC045

A - 3人でカードゲームイージー / Card Game for Three (ABC Edit) AtCoder - 2066
B - たくさんの数式 / Many Formulas AtCoder - 2067
C - すぬけ君の塗り絵 / Snuke’s Coloring AtCoder - 2068
D - すぬけ君の地下鉄旅行 / Snuke’s Subway Trip AtCoder - 2069
[TOC]

A

三个人玩纸牌游戏
模拟就可以了

#include
#include
#define MAXN 105
char a[MAXN],b[MAXN],c[MAXN];
int main()
{
    scanf("%s\n%s\n%s",a+1,b+1,c+1);
    int la=strlen(a+1),lb=strlen(b+1),lc=strlen(c+1);
    int na=2,nb=1,nc=1;
    char turn=a[1];
    while(1)
    {
        if(turn=='a')
        {
            if(na>la){printf("A\n"); return 0;}
            turn=a[na];
            na++;
        }
        if(turn=='b')
        {
            if(nb>lb){printf("B\n"); return 0;}
            turn=b[nb];
            nb++;
        }
        if(turn=='c')
        {
            if(nc>lc){printf("C\n"); return 0;}
            turn=c[nc];
            nc++;
        }
    }
}

B

搜索枚举反倒不好做,因为加号个数也不定,递归结构看起来更清晰

#include
#include
using namespace std;
#define MAXN 15
#define LL long long
char s[MAXN];
int digit[MAXN];
LL ans,N;
LL Pow(int x)
{
    LL res=1;
    while(x--)
        res*=10;
    return res;
}
int Abs(int x)
{
    if(x>0) return x;
        else return -x;
}
void dfs(int pos,LL sum,LL last)
{
    if(pos>N)
    {
        ans=ans+sum+last;
        return ;
    }
    dfs(pos+1,sum,last*10+digit[pos]);
    dfs(pos+1,sum+last,digit[pos]);
}
int main()
{
    scanf("%s",s+1);
    N=strlen(s+1);
    for(int i=1;i<=N;i++)
        digit[i]=s[i]-'0';
    dfs(2,0,digit[1]);
    //注意第一种情况确定,第一个数前面不能加'+',第一位一定是第一个加数的第一位
    printf("%lld\n",ans);
}

C

有一个H行W列的矩阵,其中有N个方格会被涂黑,第i个被涂黑的方格的坐标是ai、bi,问对于每一个3×3×3的小矩阵,有多少个小矩阵中有i格被涂黑了,输出10行,为i从0~9的答案

用总数依次减

#include
#include
#include
using namespace std;
#define LL long long
LL H,W,N;
LL ans[10];
LL dx[]={-2,-2,-2,-1,-1,-1,0,0,0};
LL dy[]={-2,-1,0,-2,-1,0,-2,-1,0};
map m;
void slove(LL x,LL y)
{
    LL a,b;
    LL id;
    for(int i=0;i<9;i++){
        a=x+dx[i];
        b=y+dy[i];
        if(a<1 || b<1 || a>H-2 || b>W-2)   continue;
        id=(H-2)*(b-1)+a;//对每个小矩形进行编号
        //左上角的位置就只能在(h-2)*(w-2)的矩形区域内
        //每一行有w-2个元素 a-1
        m[id]++;
    }
}
int main(){
    LL x,y;
    scanf("%lld %lld %lld",&H,&W,&N);
    for(int i=1;i<=N;i++)
    {
        scanf("%lld %lld",&x,&y);
        slove(x,y);
    }
    ans[0]=(H-2)*(W-2);//总数
    LL temp;
    map::iterator it=m.begin();
    for(it=m.begin();it!=m.end();it++){
        temp=it->second;
        ans[temp]++;
        ans[0]--;
    }
    for(int i=0;i<=9;i++)
        cout<return 0;
}

D

D城有 n 个传送基站,构成了由 m 对传送门组成的交通网络,每个传送门有一个属性 c 。当你使用一个传送门时,你需要使你身上的属性与传送门的属性相同。改变一次属性的代价为 1 ,经过传送门后,身上的属性不会消失。初始状态下,你身上的属性为 0 。

请你求出从 1 号基站到 n 号基站的最小代价。

说白了其实就是换乘

这道题琢磨了很久 觉得连虚边那个方法靠谱一点

/*
map : count()返回被查找元素的个数 有返回1 无返回0  注意map中不存在相同元素 (下标,即first)
        find()返回位置 若没有则返回map.end()
拆点
*/
#include
#include
#include
#include
#include
using namespace std;
#define LL long long
#define MAXN 100005
#define INF 1000000000
int N,M,cnt;
map<int,int> id[2*MAXN];//id[u][c]:u属性为c的虚点编号
vector< pair<int,int> > G[5*MAXN];
int dist[5*MAXN];
bool vis[5*MAXN];
void mg()
{
    for(int i=0;iint u,v,c;
        scanf("%d %d %d",&u,&v,&c);
        if(!id[u].count(c)) 
        {
            id[u][c]=++cnt;
            G[u].push_back(make_pair(cnt,1));
            G[cnt].push_back(make_pair(u,1));
        }
        if(!id[v].count(c)) 
        {
            id[v][c]=++cnt;
            G[v].push_back(make_pair(cnt,1));
            G[cnt].push_back(make_pair(v,1));
        }
        G[id[u][c]].push_back(make_pair(id[v][c],0));
        G[id[v][c]].push_back(make_pair(id[u][c],0));
    }
}
void sp()
{
    fill(dist,dist+5*MAXN,INF);
    dist[1]=0;
    vis[1]=1;
    queue<int> que;
    que.push(1);
    while(!que.empty())
    {
        int u=que.front();
        que.pop();
        for(int i=0;iint v=G[u][i].first,l=G[u][i].second;
            if(dist[v]>dist[u]+l)
            {
                dist[v]=dist[u]+l;
                if(!vis[v])
                {
                    vis[v]=1;
                    que.push(v);
                }
            }
        }
        vis[u]=0;
    }
}
int main()
{
    scanf("%d %d",&N,&M);
    cnt=N;
    mg();
    sp();
    if(dist[N]==INF) printf("-1\n");
    else printf("%d\n",dist[N]/2);
    return 0;
}

你可能感兴趣的:(练习赛)