比赛链接:https://ac.nowcoder.com/acm/contest/12606#question
队友写的,求最小外接圆直径
/*Siberian Squirrel*/
/*Cute JinFish*/
#include
#define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
//#define ACM_LOCAL
using namespace std;
typedef long long ll;
const double PI = acos(-1);
const double eps = 1e-4;
/*const int MOD = 998244353, r = 119, k = 23, g = 3;
const int MOD = 1004535809, r = 479, k = 21, g = 3;*/
const int MOD = 1e9 + 7;
const int M = 1e7 + 10;
const int N = 4e5 + 10;
int dcmp(double x) {
if(fabs(x) < eps) return 0;
else return x < 0? -1: 1;
}
//inline int rnd(){static int seed=2333;return seed=(((seed*666666ll+20050818)%998244353)^1000000007)%1004535809;}
int n;
struct nodee {
double x, y, z;
} _p[N];
struct node {
double x, y;
} p[N];
node c; ///圆心
double r; ///半径
int sgn(double x) {
if (fabs(x) < eps)
return 0;
else
return x < 0 ? -1 : 1;
}
double Distance(node A, node B) {
///两点距离
return hypot(A.x - B.x, A.y - B.y); ///hypot(a, b)求以a, b为直角边的直角三角形斜边长
}
///求三角形abc的外接圆圆心
node circle_center(const node a, const node b, const node c) {
node center;
double a1 = b.x - a.x, b1 = b.y - a.y, c1 = (a1 * a1 + b1 * b1) / 2;
double a2 = c.x - a.x, b2 = c.y - a.y, c2 = (a2 * a2 + b2 * b2) / 2;
double d = a1 * b2 - a2 * b1;
center.x = a.x + (c1 * b2 - c2 * b1) / d;
center.y = a.y + (a1 * c2 - a2 * c1) / d;
return center;
}
///求最小圆覆盖,返回圆心c和半径r:
void min_cover_circle(int n) {
random_shuffle(p, p + n); ///打乱所有点
c = p[0];
r = 0; ///第一个点
for (int i = 1; i < n; ++i) {
///剩下所有点
if (sgn(Distance(p[i], c) - r) > 0) {
///pi在圆外部
c = p[i];
r = 0; ///将圆心设为pi半径为0
for (int j = 0; j < i; ++j) {
///重新检查前面的点
if (sgn(Distance(p[j], c) - r) > 0) {
///两点定圆
c.x = (p[i].x + p[j].x) / 2;
c.y = (p[i].y + p[j].y) / 2;
r = Distance(p[j], c);
for (int k = 0; k < j; ++k) {
if (sgn(Distance(p[k], c) - r) > 0) {
c = circle_center(p[i], p[j], p[k]);
r = Distance(p[i], c);
}
}
}
}
}
}
}
inline void solve(ll res = 0) {
double minn = 1.0 * INT_MAX;
for(int i = 0; i < n; ++ i) {
p[i].x = _p[i].x;
p[i].y = _p[i].y;
}
min_cover_circle(n);
// cout << "1:" << setprecision(10) << r * 2 << endl;
minn = min(minn, 2.0 * r);
for(int i = 0; i < n; ++ i) {
p[i].x = _p[i].x;
p[i].y = _p[i].z;
}
min_cover_circle(n);
// cout << "2:" << setprecision(10) << r * 2 << endl;
minn = min(minn, 2.0 * r);
for(int i = 0; i < n; ++ i) {
p[i].x = _p[i].z;
p[i].y = _p[i].y;
}
min_cover_circle(n);
// cout << "3:" << setprecision(10) << r * 2 << endl;
minn = min(minn, 2.0 * r);
cout << setprecision(10) << minn << endl;
}
int main() {
IO;
#ifdef ACM_LOCAL
freopen("input", "r", stdin);
freopen("output", "w", stdout);
#endif
int o = 1;
// cin >> o;
while(o --) {
cin >> n;
for(int i = 0; i < n; ++ i) {
cin >> _p[i].x >> _p[i].y >> _p[i].z;
}
solve();
}
return 0;
}
一开始觉得是二分图,后来发现这根本就不是二分图 ,浪费了1个多小时在这个上面还是挺傻逼的,稍加思考其实就是个带花树的裸题而已,不懂带花树的搜一下一般图的最大匹配,然后这题就是个最大独立集也就是n-最大匹配数。
#include
using namespace std;
#define re register
#define fi first
#define se second
const int N = 1e5 + 10;
const int M = 1e6 + 10;
const int INF = 0x3f3f3f3f;
const double eps = 1e-4;
const int MOD = 1e9 + 7;
typedef long long ll;
int n;
string s[N];
char ai[N], bi[N];
int m,cnt,last[N],ty[N],tic[N],tim,f[N],match[N],pre[N];
struct edge{
int to,next;}e[300005];
queue<int> que;
int read()
{
int x=0,f=1;char ch=getchar();
while (ch<'0'||ch>'9'){
if(ch=='-')f=-1;ch=getchar();}
while (ch>='0'&&ch<='9'){
x=x*10+ch-'0';ch=getchar();}
return x*f;
}
void addedge(int u,int v)
{
e[++cnt].to=v;e[cnt].next=last[u];last[u]=cnt;
e[++cnt].to=u;e[cnt].next=last[v];last[v]=cnt;
}
int find(int x)
{
if (f[x]==x) return x;
else return f[x]=find(f[x]);
}
int lca(int x,int y)
{
for (tim++;;swap(x,y))
if (x)
{
x=find(x);
if (tic[x]==tim) return x;
tic[x]=tim;x=pre[match[x]];
}
}
void shrink(int x,int y,int p)
{
while (find(x)!=p)
{
pre[x]=y;y=match[x];
if (ty[y]==2) ty[y]=1,que.push(y);
if (find(x)==x) f[x]=p;
if (find(y)==y) f[y]=p;
x=pre[y];
}
}
bool aug(int s)
{
for (int i=1;i<=n;i++) f[i]=i,ty[i]=pre[i]=0;
while (!que.empty()) que.pop();
que.push(s);ty[s]=1;
while (!que.empty())
{
int x=que.front();que.pop();
for (int i=last[x],y=e[i].to;i;i=e[i].next,y=e[i].to)
{
if (find(x)==find(y)||ty[y]==2) continue;
if (!ty[y])
{
ty[y]=2;pre[y]=x;
if (!match[y])
{
for (int tmp;y;y=tmp,x=pre[y])
tmp=match[x],match[x]=y,match[y]=x;
return 1;
}
else ty[match[y]]=1,que.push(match[y]);
}
else if (ty[y]==1)
{
int p=lca(x,y);
shrink(x,y,p);
shrink(y,x,p);
}
}
}
return 0;
}
void solve() {
cin >> n;
for (int i = 1; i <= n; i++) cin >> s[i];
for (int i = 1; i <= n; i++) {
for (int j = i+1; j <= n; j++) {
int num = 0;
for (int k = 0; k < s[i].size(); k++) {
if (s[i][k] != s[j][k]) {
num++;
if (num <= 2) ai[num] = s[i][k], bi[num] = s[j][k];
}
}
if (num == 2 && ai[1] == bi[2] && ai[2] == bi[1]) addedge(i, j);
}
}
int ans = 0;
for (int i = 1; i <= n; i++) {
if (!match[i] && aug(i)) ans++;
}
cout << n - ans << endl;
}
signed main() {
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
#ifdef ACM_LOCAL
freopen("input", "r", stdin);
freopen("output", "w", stdout);
#endif
solve();
}
队友写的签到题
/*Siberian Squirrel*/
/*Cute JinFish*/
#include
#define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
//#define ACM_LOCAL
using namespace std;
typedef long long ll;
const double PI = acos(-1);
const double eps = 1e-6;
/*const int MOD = 998244353, r = 119, k = 23, g = 3;
const int MOD = 1004535809, r = 479, k = 21, g = 3;*/
const int MOD = 1e9 + 7;
const int M = 1e7 + 10;
const int N = 4e5 + 10;
int dcmp(double x) {
if(fabs(x) < eps) return 0;
else return x < 0? -1: 1;
}
//inline int rnd(){static int seed=2333;return seed=(((seed*666666ll+20050818)%998244353)^1000000007)%1004535809;}
int n;
inline void solve(ll res = 0) {
if(n & 1) cout << "Either" << endl;
else if((n / 2) % 2 == 0) cout << "Even" << endl;
else cout << "Odd" << endl;
}
int main() {
IO;
#ifdef ACM_LOCAL
freopen("input", "r", stdin);
freopen("output", "w", stdout);
#endif
int o = 1;
// cin >> o;
while(o --) {
cin >> n;
solve();
}
return 0;
}
因为取牌是有后效性的,也就是说你要提前处理出所有数值的牌还剩多少张,然后就是用单调栈进行贪心了。我们要维护单调栈内递增,这样可以做到当前最优的状态,然后配合预处理的牌的张数进行出栈。有一个地方要特殊注意一下,如果这个数值已经在栈内了,那就直接过。
#include
using namespace std;
#define re register
#define fi first
#define se second
const int N = 2e5 + 10;
const int M = 1e6 + 10;
const int INF = 0x3f3f3f3f;
const double eps = 1e-4;
const int MOD = 1e9 + 7;
typedef long long ll;
int a[N], cnt[N];
int stk[N], tp, vis[N];
void solve() {
int n, m; cin >> n >> m;
for (int i = 1; i <= n; i++) cin >> a[i], cnt[a[i]]++;
for (int i = 1; i <= n; i++) {
if (!vis[a[i]]) {
while (tp && a[stk[tp]] > a[i] && cnt[a[stk[tp]]]) {
vis[a[stk[tp]]] = 0;
tp--;
}
stk[++tp] = i;
vis[a[i]] = 1;
}
//for (int j = 1; j <= tp; j++) cout << a[stk[j]] << " ";
//cout << endl;
cnt[a[i]]--;
}
for (int i = 1; i <= tp; i++) cout << a[stk[i]] << " ";
}
signed main() {
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
#ifdef ACM_LOCAL
freopen("input", "r", stdin);
freopen("output", "w", stdout);
#endif
solve();
}
数值很小,直接处理前缀和后缀和,枚举每个数就可以了,简单签到题
#include
using namespace std;
#define re register
#define fi first
#define se second
const int N = 1e5 + 10;
const int M = 1e6 + 10;
const int INF = 0x3f3f3f3f;
const double eps = 1e-4;
const int MOD = 1e9 + 7;
typedef long long ll;
int n, m, a[N];
ll pre[N], back[N], cnt[N];
void solve() {
cin >> n;
for (int i = 1; i <= n; i++) cin >> a[i], cnt[a[i]]++;
for (int i = 1; i <= 1e5; i++) pre[i] = pre[i-1] + cnt[i] * i;
for (int i = 1e5; i >= 1; i--) back[i] = back[i+1] + cnt[i] * i;
for (int i = 1; i <= 1e5; i++) {
if (pre[i-1] == back[i+1]) {
printf("%d\n", i);
return;
}
}
}
signed main() {
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
#ifdef ACM_LOCAL
freopen("input", "r", stdin);
freopen("output", "w", stdout);
#endif
solve();
}
题目花里胡哨,其实就是一个bfs(最短路-1也可以)
#include
using namespace std;
#define re register
#define fi first
#define se second
const int N = 2e5 + 10;
const int M = 1e6 + 10;
const int INF = 0x3f3f3f3f;
const double eps = 1e-4;
const int MOD = 1e9 + 7;
typedef long long ll;
typedef pair<int, int> PII;
struct Edge {
int to, next, w;
}e[M];
int h[N], cnt, vis[N], dis[N];
void add(int u, int v) {
e[cnt].to = v;
e[cnt].next = h[u];
h[u] = cnt++;
}
void bfs(int s) {
queue<int> que;
memset(dis, 0x3f, sizeof dis);
for (int i = h[s]; ~i; i = e[i].next) dis[e[i].to] = 0, que.push(e[i].to);
vis[s] = 1; dis[s] = 0;
while (que.size()) {
int now = que.front();
que.pop();
vis[now] = 1;
for (int i = h[now]; ~i; i = e[i].next) {
int v = e[i].to;
dis[v] = min(dis[v], dis[now] + 1);
if (!vis[v]) que.push(v);
}
}
}
void solve() {
int n, m; cin >> n >> m;
memset(h, -1, sizeof h);
for (int i = 1; i <= m; i++) {
int u, v; cin >> u >> v;
add(u, v); add(v, u);
}
bfs(1);
cout << dis[n] << endl;
}
signed main() {
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
#ifdef ACM_LOCAL
freopen("input", "r", stdin);
freopen("output", "w", stdout);
#endif
solve();
}
树形dp,需要预处理一些东西
T代表子树节点权值和
siz代表子树子节点个数
dist代表所有子节点到当前节点的距离和
disT代表所有子节点到当前节点距离*子节点的和
然后就可以开始转移了
根转移写得少,代码略丑
#include
using namespace std;
//#define ACM_LOCAL
#define re register
#define fi first
#define se second
const int N = 3e5 + 10;
const int M = 1e6 + 10;
const int INF = 0x3f3f3f3f;
const double eps = 1e-4;
const int MOD = 1e9 + 7;
typedef long long ll;
typedef pair<int, int> PII;
ll T[N], dist[N], disT[N], val[N], siz[N], ans[N];
int cnt, h[N], n, m;
struct Edge {
int to, next, w;
}e[M];
void add(int u, int v, int w) {
e[cnt].to = v;
e[cnt].w = w;
e[cnt].next = h[u];
h[u] = cnt++;
}
void dfs1(int u, int fa) {
siz[u] = 1; T[u] = val[u];
for (int i = h[u]; ~i; i = e[i].next) {
int v = e[i].to;
if (v == fa) continue;
dfs1(v, u);
siz[u] += siz[v];
T[u] += T[v];
dist[u] += siz[v] * e[i].w + dist[v];
disT[u] += e[i].w * T[v] + disT[v];
}
}
void dfs2(int u, int fa) {
for (int i = h[u]; ~i; i = e[i].next) {
int v = e[i].to;
if (v == fa) continue;
dist[v] += dist[u] - dist[v] - e[i].w * siz[v] + (siz[u] - siz[v]) * e[i].w;
disT[v] += disT[u] - disT[v] - e[i].w * T[v] + (T[u] - T[v]) * e[i].w;
ans[v] = val[v] * dist[v] + disT[v];
siz[v] = siz[u];
T[v] = T[u];
dfs2(v, u);
}
}
void solve() {
cin >> n;
memset(h, -1, sizeof h);
for (int i = 1; i <= n; i++) cin >> val[i];
for (int i = 1; i <= n-1; i++) {
int u, v, w; cin >> u >> v >> w;
add(u, v, w), add(v, u, w);
}
dfs1(1, 0);
ans[1] = disT[1] + dist[1] * val[1];
dfs2(1, 0);
for (int i = 1; i <= n; i++) printf("%lld\n", ans[i]);
}
signed main() {
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
#ifdef ACM_LOCAL
freopen("input", "r", stdin);
freopen("output", "w", stdout);
#endif
solve();
}
签到题
#include
using namespace std;
#define re register
#define fi first
#define se second
const int N = 2e5 + 10;
const int M = 1e6 + 10;
const int INF = 0x3f3f3f3f;
const double eps = 1e-4;
const int MOD = 1e9 + 7;
typedef long long ll;
typedef pair<int, int> PII;
int mp[100][100];
void solve() {
int n; cin >> n;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
char c; cin >> c;
if (c == 'W') mp[i][j] = 0;
else mp[i][j] = 1;
}
}
int f = 0;
for (int i = 1; i <= n; i++) {
int black = 0, white = 0;
for (int j = 1; j <= n; j++) {
if (mp[i][j] == 0) white++;
else black++;
}
if (white != black) f = 1;
}
for (int i = 1; i <= n; i++) {
int black = 0, white = 0;
for (int j = 1; j <= n; j++) {
if (mp[j][i] == 0) white++;
else black++;
}
if (white != black) f = 1;
}
for (int i = 1; i <= n; i++) {
int tmp = 1;
for (int j = 2; j <= n; j++) {
if (mp[i][j] == mp[i][j-1]) tmp++;
else tmp = 1;
if (tmp >= 3) f = 1;
}
}
for (int i = 1; i <= n; i++) {
int tmp = 1;
for (int j = 2; j <= n; j++) {
if (mp[j][i] == mp[j-1][i]) tmp++;
else tmp = 1;
if (tmp >= 3) f = 1;
}
}
if (f) cout << 0 << endl;
else cout << 1 << endl;
}
signed main() {
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
#ifdef ACM_LOCAL
freopen("input", "r", stdin);
freopen("output", "w", stdout);
#endif
solve();
}