要想每个奶牛都能到达牧场,以(k 个奶牛)每个奶牛的位置为起点做一次 dfs/bfs,标记可以到达的点。哪些结点被标记了 k 次,即为所求结果。
代码:
#include<iostream>#include<cstring>#include<vector>usingnamespace std;
constint N = 1010;
int k, n, m;
int a[N]; // k 头奶牛的编号
vector<int> edges[N];
int cnt[N];
bool st[N];
voiddfs(int u){
st[u] = true;
cnt[u]++;
for (int v : edges[u]) {
if (!st[v]) dfs(v);
}
}
intmain(){
cin >> k >> n >> m;
for (int i = 1; i <= k; i++) cin >> a[i];
for (int i = 1; i <= m; i++) {
int x, y;
cin >> x >> y;
edges[x].push_back(y);
}
for (int i = 1; i <= k; i++) {
memset(st, 0, sizeof st); // 重置更新为 0dfs(a[i]);
}
int ret = 0;
for (int i = 1; i <= n; i++) {
if (cnt[i] == k) ret++;
}
cout << ret << endl;
return0;
}
政府规定价格 aim,成本:a,销量:c[i],表示售价为 i 时的对应销量。
(aim - a + x) * c[aim] >= (i - a + x) * c[i]
(aim - a) * c[aim] + x * c[aim] >= (i - a) * c[i] + x * c[i]
x * (c[aim] - c[i]) >= (i - a) * c[i] - (aim - a) * c[aim]
c[aim] > c[i], x >= ((i - a) * c[i] - (aim - a) * c[aim]) / (c[aim] - c[i])
c[aim] < c[i], x <= ((i - a) * c[i] - (aim - a) * c[aim]) / (c[aim] - c[i])
细节处理:
left < x < right。
left > right,x 无解;
right < 0, left < 0,x 取绝对值较小,值较大的,就是舍(向下取整),用 floor(right);
right > 0, left > 0,x 取绝对值较小,值较小的,就是入(向上取整),用 ceil(left);
left < 0, right > 0,x 取绝对值较小,取 0。
代码:
#include<iostream>#include<cmath>usingnamespace std;
constint N = 1e5 + 10;
int aim, a;
int c[N]; // 售价为 i 时,销量为 c[i]intmain(){
cin >> aim;
int x, y;
cin >> x >> y;
a = x;
c[x] = y;
int prev = x; // 存前一个的定价while (cin >> x >> y, x != -1 && y != -1) {
int d = (c[prev] - y) / (x - prev);
for (int i = prev + 1, j = c[prev] - d; i <= x; i++, j -= d) {
c[i] = j;
}
prev = x;
}
int d;
cin >> d;
for (int i = prev + 1, j = c[prev] - d; j >= 0; i++, j -= d) {
c[i] = j;
prev = i;
}
double left = -1e9, right = 1e9;
for (int i = a; i <= prev; i++) {
double val = 1.0 * ((i - a) * c[i] - (aim - a) * c[aim]) / (c[aim] - c[i]);
if (c[aim] > c[i]) left = max(left, val);
elseif (c[aim] < c[i]) right = min(right, val);
}
if (left > right) cout << "NO SOLUTION" << endl;
elseif (right < 0) cout << (int)floor(right) << endl;
elseif (right > 0) cout << (int)ceil(left) << endl;
else cout << 0 << endl;
return0;
}