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]
三个人玩纸牌游戏
模拟就可以了
#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++;
}
}
}
搜索枚举反倒不好做,因为加号个数也不定,递归结构看起来更清晰
#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);
}
有一个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城有 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;
}