A.
https://ac.nowcoder.com/acm/contest/5026/A
题意:给你怪物和勇士 血量和攻击 问勇士能杀几个怪物
思路:先计算勇士杀死怪物要几回合 如果勇士能一刀秒的话 就是无限个 否则计算杀死单个怪物勇士要掉多少血 根据总的计算就好了
#include <bits/stdc++.h>
using namespace std;
#define LL long long
#define mes(x,a) memset(x,a,sizeof(x));
#define sca(a) scanf("%d",&a)
#define lowbit(x) x & (-x)
#define fi first
#define se second
#define pii pair<int, int>
inline int read()
{
int x=0,flag_read=1;
char c=getchar();
while(c<'0'||c>'9')
{
if(c=='-')
flag_read=-1;
c=getchar();
}
while(c>='0'&&c<='9')
{
x=(x<<3)+(x<<1)+c-'0';
c=getchar();
}
return x*flag_read;
}
const double eps=1e-9;
const double pi=acos(-1);
const int N = 1e6+5;
const int M = 1e7+5;
const int INF = 0x3f3f3f3f;
const int mod=2e6+5;
int main()
{
ios::sync_with_stdio(false);
int t; cin >> t;
while(t --)
{
int a,b,c,d;
cin >> a >> b >> c >> d;
if(b >= c)
{
cout << -1 << '\n';
continue;
}
int x = a / d;
if(a%d)
x ++ ;
c -= b;///由勇士先手
int y = c/b;
if(c%b)
y ++ ;
int res = x / y;
if(x%y == 0)
res -- ;
cout << res << '\n';
}
return 0;
}
B.
https://ac.nowcoder.com/acm/contest/5026/B
思路:如果2n = m话 答案就是m + 1
2n > m 话 我们假设过了 x 天 2(n - x) =(m - x) 所以 x = 2n - m
我们直接考虑对答案的贡献 花了x天使 n * 2 = m 花1天翻倍 然后m只剩下m -x 个 所以 答案为x+1+m - x = m +1
如果 2n < m 就花费天数使得其变为 2n >= m即可
#include <bits/stdc++.h>
using namespace std;
#define LL long long
#define mes(x,a) memset(x,a,sizeof(x));
#define sca(a) scanf("%d",&a)
#define lowbit(x) x & (-x)
#define fi first
#define se second
#define pii pair<int, int>
inline int read()
{
int x=0,flag_read=1;
char c=getchar();
while(c<'0'||c>'9')
{
if(c=='-')
flag_read=-1;
c=getchar();
}
while(c>='0'&&c<='9')
{
x=(x<<3)+(x<<1)+c-'0';
c=getchar();
}
return x*flag_read;
}
const double eps=1e-9;
const double pi=acos(-1);
const int N = 1e6+5;
const int M = 1e7+5;
const int INF = 0x3f3f3f3f;
const int mod=2e6+5;
int main()
{
ios::sync_with_stdio(false);
int t; cin >> t;
while(t --)
{
LL n, m;
cin >> n >> m;
if(n == m)
{
cout << 1 << '\n';
continue;
}
LL mi = min(n , m);
LL ma = max(n , m);
LL res = 0;
if(2*mi >= ma)
res = ma + 1;
else
{
LL x = mi;
int sum = 0;
while(x*2 < ma)
sum ++ , x*= 2;
res = ma + 1 + sum ;
}
cout << res << '\n';
}
return 0;
}
C
https://ac.nowcoder.com/acm/contest/5026/C
题意:求四个选项符合条件的种类
思路:dfs + 并查集 答案要求相同的通过并查集合并 然后dfs求联通块种类个数
#include <bits/stdc++.h>
using namespace std;
int fa[15],vis[15],res[15];
int a,b,c,d,m,cnt;
int sum;
int findx(int x)
{
if(x != fa[x])
return fa[x] = findx(fa[x]);
return x;
}
void join(int x,int y)
{
int xx = findx(x);
int yy = findx(y);
if(xx != yy)
fa[xx] = yy;
}
void dfs(int x)
{
if(x > cnt)
{
sum ++ ;
return ;
}
if(a >= res[x])a -= res[x],dfs(x + 1),a += res[x];
if(b >= res[x])b -= res[x],dfs(x + 1),b += res[x];
if(c >= res[x])c -= res[x],dfs(x + 1),c += res[x];
if(d >= res[x])d -= res[x],dfs(x + 1),d += res[x];
}
int main()
{
cin >> a >> b >> c >> d >> m ;
for(int i = 1;i <= 15;i ++)
fa[i] = i;
while(m --)
{
int u,v;
cin >> u >> v;
join(u,v);
}
for(int i = 1;i <= 12;i ++)
{
int father = findx(i);
if(!vis[father])
{
res[++ cnt] ++ ;
vis[father] = cnt;
}
else
res[vis[father]] ++ ;
}
dfs(1);
cout << sum << '\n';
return 0;
}
D.
https://ac.nowcoder.com/acm/contest/5026/D
题意:将图中某一条边置反 问最短路是否会变短
思路:跑询问次数的dj是不现实的 我们以1为源点 n为源点跑最短路
如果dist1[v] + dist2[u] + w < dist[n] 就是YES 否则就是NO
我们将这条边置反后 判断从1到v的距离 和 从n到u的距离 如果走过该条置反的边会使得答案到n的距离会更短 那显然就是正确的
#include <bits/stdc++.h>
using namespace std;
const int N = 100005,M = 150005;
const long long INF = 0x7fffffffffffffff;
int n, m;
#define int long long
struct node
{
int to;
int w;
node() {}
node(int tt,int ww):to(tt),w(ww) {};
friend bool operator < (const node &a,const node &b)
{
return a.w > b.w;
}
};
struct quest
{
int u,v,w;
} q[200005];
struct dijkstra
{
int dist[N],head[N], cnt;
bool vis[N];
struct Edge
{
int to;
int w;
int next;
} edge[M << 1];
void init()
{
memset(head,-1,sizeof (head) );
for(int i = 0; i <= n; i ++)
{
dist[i] = INF;
vis[i] = 0;
}
cnt = 0;
}
void addEdge(int u,int v,int w)
{
edge[cnt].to = v;
edge[cnt].w = w;
edge[cnt].next = head[u];
head[u] = cnt ++ ;
}
void dj(int s,int t)
{
priority_queue <node> que;
dist[s] = 0;
que.push(node{s,0});
while(!que.empty())
{
node now = que.top();
que.pop();
if(!vis[now.to])
{
vis[now.to] = 1;
for(int i = head[now.to]; ~i ; i = edge[i].next)
{
int to = edge[i].to;
int w = edge[i].w;
if(!vis[to] && dist[to] > dist[now.to] + edge[i].w)
{
dist[to] = dist[now.to] + edge[i].w;
que.push(node(to,dist[to]));
}
}
}
}
// return dist[t];
}
} a,b;
signed main()
{
cin >> n >> m;
a.init();
b.init();
for(int i = 1; i <= m; i ++)
{
int u,v,w;
cin >> u >> v >> w;
a.addEdge(u,v,w);
b.addEdge(v,u,w);
q[i] = {u,v,w};
}
a.dj(1,n);
b.dj(n,1);
int k ;
cin >> k;
while(k --)
{
int x;
cin >> x;
int u = q[x].u;
int v = q[x].v;
int w = q[x].w;
if(a.dist[v] + b.dist[u] + w < a.dist[n])
puts("YES");
else
puts("NO");
}
return 0;
}