C - たくさんの数式 / Many Formulas
思路:假设字符串长度为len,则有len-1个空,插入+号共2^(len-1)中方法,枚举每一个状态算加和即可。
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
char str[100];
int len,pnum;
LL calc(int s, int t)
{
LL ret = 0;
for(int i = s; i < t; ++i)
ret = ret*10 + str[i]-'0';
return ret;
}
int main()
{
scanf("%s",str);
len = strlen(str);
pnum = len-1;
int st = 1<<pnum;
int pre = 0,now,nst;
LL res = 0;
for(int i = 0; i < st; ++i)
{
pre = 0;
for(int j = 0; j <= 15; ++j)
{
if((1<<j)&i)
{
now = j;
res += calc(pre,now+1);
pre = now+1;
}
}
res += calc(pre,len);
}
printf("%lld
",res);
return 0;
}
D - すぬけ君の塗り絵 / Snuke's Coloring
思路:对于给出的每个黑色方块,这么一个方块最多被9个3 * 3的矩阵包含。每个3 * 3的矩阵以其左下角的方块的坐标来表示这个矩阵。对于每个黑块,计算出包含他的9个3 * 3的矩阵,他对每个3 * 3矩阵贡献+1。每个矩阵被几个黑色的方块贡献过,他就包含几个黑色方块。用map统计下就好。
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
int dx[9] = {-2, -2, -2, -1, -1, -1, 0, 0, 0};
int dy[9] = {-2, -1, 0, -2, -1, 0,-2,-1, 0};
LL res[10];
int H,W,N;
map<pair<int,int>, int> mp;
int main()
{
ios::sync_with_stdio(false);
cin >> H >> W >> N;
res[0] = (LL)(H-2)*(LL)(W-2);
int u,v,tx,ty;
for(int i = 0; i < N; ++i)
{
cin >> u >> v;
for(int k = 0; k < 9; ++k)
{
tx = u + dx[k];
ty = v + dy[k];
if(tx < 1 || ty < 1 || tx > H-2 || ty > W-2) continue;
mp[make_pair(tx,ty)]++;
}
}
for(pair<pair<int,int>,int> pa : mp)
{
--res[0];
++res[pa.second];
}
for(int i = 0; i <= 9; ++i)
cout << res[i] <<endl;
return 0;
}
E - すぬけ君の地下鉄旅行 / Snuke's Subway Trip
思路:本来以为是dp呢,从N dp到 1,想了想,我的想法行不通。搜题解是拆点,然后跑最短路。http://blog.csdn.net/keyboarderqq/article/details/52558272 , https://www.cnblogs.com/mcginn/p/5870586.html 感觉这题这种建图方式很棒。比如u,v,c,(u,c)看作一个点,(v,c)看作一个点。(u,c)和(v,c)相连,花费为0。u和(u,c)相连花费为1,v和(v,c)相连花费为1。u和v就像是入口和出口,中间(u,c)和(v,c)之间是专用通道。在这个通道内不花钱。只有进入和出去花钱。这样正好能够把同一家公司经营的而且连着的通道放到同一个专用通道内。
#include <bits/stdc++.h>
using namespace std;
struct qnode
{
int v,c;
qnode(int _v = 0, int _c = 0):v(_v),c(_c) {}
bool operator<(const qnode& b) const
{
return c > b.c;
}
};
struct Edge
{
int v,cost;
Edge(int _v = 0, int _cost = 0):v(_v),cost(_cost) {}
};
const int MAXN = 1e6+10;
const int INF = 0x3f3f3f3f;
map<pair<int, int>, int> mp;
int n,m,st;
vector<Edge> E[MAXN];
bool vis[MAXN];
int dist[MAXN];
void addedge(int u, int v, int w)
{
E[u].push_back(Edge(v,w));
}
void Dijkstra(int n, int start)
{
memset(vis,0,sizeof(vis));
memset(dist,INF,sizeof(dist));
priority_queue<qnode> que;
dist[start] = 0;
que.push(qnode(start,0));
qnode tmp;
while(!que.empty())
{
tmp = que.top();
que.pop();
int u = tmp.v;
if(vis[u]) continue;
vis[u] = true;
for(int i = 0; i < E[u].size(); ++i)
{
int v = E[tmp.v][i].v;
int cost = E[u][i].cost;
if(!vis[v] && dist[v] > dist[u]+cost)
{
dist[v] = dist[u]+cost;
que.push(qnode(v,dist[v]));
}
}
}
}
void init()
{
st = n;
}
int getid(int u, int c)
{
if(mp.find(make_pair(u,c)) != mp.end())
return mp[make_pair(u,c)];
return mp[make_pair(u,c)] = ++st;
}
int main()
{
int a,b,c,ta,tb;
scanf("%d %d",&n,&m);
init();
for(int i = 0; i < m; ++i)
{
scanf("%d %d %d",&a,&b,&c);
ta = getid(a,c);
tb = getid(b,c);
addedge(ta,tb,0);
addedge(tb,ta,0);
addedge(a,ta,1);
addedge(ta,a,1);
addedge(b,tb,1);
addedge(tb,b,1);
}
Dijkstra(n,1);
printf("%d
",dist[n] == INF?-1:dist[n]/2);
return 0;
}
F - 3人でカードゲーム / Card Game for Three
待补