A:Zero Array

题意:两种操作, 1 p v  将第p个位置的值改成v  2  查询最少的操作数使得所有数都变为0  操作为可以从原序列中选一个非0的数使得所有非0的数减去它,并且所有数不能变为负数

思路:考虑第二种操作,显然,最少的操作数肯定是不同数的个数 用map 记录,特殊注意0的存在

 #include <bits/stdc++.h>

 using namespace std;

 #define N 100010

 unordered_map <int, int> mp;

 int t, n, q;

 int arr[N];

 int main()
{
cin.tie();
cout.tie();
ios::sync_with_stdio(false);
cin >> t;
while (t--)
{
cin >> n >> q;
mp.clear();
for (int i = ; i <= n; ++i)
{
cin >> arr[i];
mp[arr[i]]++;
}
int op, p, v;
while (q--)
{
cin >> op;
if (op == )
{
cin >> p >> v;
if (mp[arr[p]] == )
{
mp.erase(arr[p]);
}
else
{
mp[arr[p]]--;
}
mp[v]++;
arr[p] = v;
}
else
{
mp[]++;
cout << mp.size() - << endl;
}
}
}
return ;
}

B:New Assignment

题意:给出n个人,有男生有女生,每个人有权值,进行分组,一个男的可以一组,一个女的可以一组,一男一女可以一组当且仅当他们的权值的最大公约数大于1,求最少的分组数量

思路:优先让一男一女分组,让可以一起分组的男女连边,跑二分匹配或者最大流,建图的时候注意不能够直接GCD,这样常数比较大,我们分解质因数卡卡常就可以过去

二分图匹配:

 #include <bits/stdc++.h>

 using namespace std;

 #define N 10010
#define M 1000010
#define INF 0x3f3f3f3f vector <int> G[N];
int uN, vN;
int Mx[N], My[N];
int dx[N], dy[N];
int dis;
bool used[N]; inline bool SearchP()
{
queue <int> Q;
dis = INF;
memset(dx, -, sizeof dx);
memset(dy, -, sizeof dy);
for (int i = ; i < uN; ++i)
if (Mx[i] == -)
{
Q.push(i);
dx[i] = ;
}
while (!Q.empty())
{
int u = Q.front();
Q.pop();
if (dx[u] > dis) break;
int sz = G[u].size();
for (int i = ; i < sz; ++i)
{
int v = G[u][i];
if (dy[v] == -)
{
dy[v] = dx[u] + ;
if (My[v] == -) dis = dy[v];
else
{
dx[My[v]] = dy[v] + ;
Q.push(My[v]);
}
}
}
}
return dis != INF;
} inline bool DFS(int u)
{
int sz = G[u].size();
for (int i = ; i < sz; ++i)
{
int v = G[u][i];
if (!used[v] && dy[v] == dx[u] + )
{
used[v] = true;
if (My[v] != - && dy[v] == dis) continue;
if (My[v] == - || DFS(My[v]))
{
My[v] = u;
Mx[u] = v;
return true;
}
}
}
return false;
} inline int MaxMatch()
{
int res = ;
memset(Mx, -, sizeof Mx);
memset(My, -, sizeof My);
while (SearchP())
{
memset(used, false, sizeof used);
for (int i = ; i < uN; ++i)
if (Mx[i] == - && DFS(i))
res++;
}
return res;
} int t, n; int arr[N], brr[N]; vector <int> pr[M], fac[M]; inline void Init()
{
for (int i = ; i <= ; ++i)
if (pr[i].empty())
for (int j = i; j <= ; j += i)
pr[j].emplace_back(i);
} int a[N], b[N];
map <int, bool> mp; int main()
{
Init();
scanf("%d", &t);
while (t--)
{
scanf("%d", &n);
for (int i = ; i <= n; ++i) scanf("%d", arr + i);
uN = , vN = ;
char c;
for (int i = ; i <= n; ++i)
{
scanf(" %c", &c);
if (c == 'F')
{
a[uN] = arr[i];
for (int j = , len = pr[arr[i]].size(); j < len; ++j)
{
int x = pr[arr[i]][j];
fac[x].emplace_back(uN);
}
G[uN].clear();
uN++;
}
else
{
b[vN] = arr[i];
vN++;
}
}
for (int i = ; i < vN; ++i)
{
mp.clear();
for (int j = , len = pr[b[i]].size(); j < len; ++j)
{
int x = pr[b[i]][j];
for (int k = , lenn = fac[x].size(); k < lenn; ++k)
{
int id = fac[x][k];
if (mp[id] == false)
{
mp[id] = true;
G[id].emplace_back(i);
}
}
}
}
printf("%d\n", n - MaxMatch());
for (int i = ; i < uN; ++i)
{
for (int j = , len = pr[a[i]].size(); j < len; ++j)
{
int x = pr[a[i]][j];
fac[x].clear();
}
}
}
}

最大流:

 #include<bits/stdc++.h>

 using namespace std;

 const int maxn = 1e4 + ;
const int INF = 0x3f3f3f3f; int n, m; struct Edge {
int from;
int to;
int cap;
int flow;
inline Edge(){}
inline Edge(int from, int to, int cap, int flow) :from(from), to(to), cap(cap), flow(flow) {};
}; map<pair<int, int>, bool>mp;
vector<int>pre[];
vector<int>vec[];
int arr[maxn];
int sex[maxn];
vector<Edge>edge;
vector<int>G[maxn];
int vis[maxn];
int d[maxn];
int cur[maxn];
int S, T; inline void init()
{
mp.clear();
edge.clear();
for (int i = ; i <= n + ; ++i)
{
G[i].clear();
}
} inline void addedge(int from, int to, int cap)
{
edge.push_back(Edge(from, to, cap, ));
edge.push_back(Edge(to, from, , ));
int len = edge.size();
G[from].push_back(len - );
G[to].push_back(len - );
} inline bool BFS()
{
memset(d, , sizeof d);
memset(vis, , sizeof vis);
queue<int>q;
q.push(S);
d[S] = ;
vis[S] = ;
while (!q.empty())
{
int x = q.front();
q.pop();
for (auto it : G[x])
{
Edge &e = edge[it];
if (!vis[e.to] && e.cap > e.flow)
{
vis[e.to]
= ;
d[e.to] = d[x] + ;
q.push(e.to);
}
}
}
return vis[T];
} inline int DFS(int x, int a)
{
if (x == T || a == ) return a;
int flow = ;
int f = ;
for (int &i = cur[x]; i < G[x].size(); ++i)
{
Edge &e = edge[G[x][i]];
if (d[x] + == d[e.to] && (f = DFS(e.to, min(a, e.cap - e.flow))) > )
{
e.flow += f;
edge[G[x][i] ^ ].flow-f;
flow += f;
a -= f;
if (a == ) break;
}
}
return flow;
} inline int dicnic()
{
int ans = ;
while (BFS())
{
memset(cur, , sizeof cur);
ans += DFS(S, INF);
}
return ans;
} inline void work()
{
for (int i = ; i <= ; ++i)
{
if (pre[i].size() == )
{
for (int j = i; j <= ; j += i)
{
pre[j].push_back(i);
}
}
}
} int main()
{
work();
int t;
scanf("%d", &t);
while (t--)
{
init();
scanf("%d", &n);
S = , T = n + ;
for (int i = ; i <= n; ++i)
{
scanf("%d", &arr[i]);
}
for (int i = ; i <= n; ++i)
{
char c;
scanf(" %c", &c);
if (c == 'F')
{
for (auto it : pre[arr[i]])
{
vec[it].push_back(i);
}
sex[i] = ;
}
else
{
sex[i] = ;
}
}
for (int i = ; i <= n; ++i)
{
if (sex[i] == )
{
for (auto j : pre[arr[i]])
{
for (auto k : vec[j])
{
if (mp[make_pair(i, k)] == false)
{
addedge(i, k, );
mp[make_pair(i, k)] = mp[make_pair(k, i)] = true;
}
}
}
}
}
for (int i = ; i <= n; ++i)
{
if (sex[i] == ) addedge(, i, );
else if (sex[i] == ) addedge(i, n + , );
}
int ans = n - dicnic();
printf("%d\n", ans);
for (int i = ; i <= n + ; ++i)
{
for (auto x : pre[arr[i]])
{
vec[x].clear();
}
}
}
return ;
}

C:Intersections

题意:给出两个数组,数组里面是相同的数,然后相同的数之间连边,求有多少交点,交点重叠算多个点

思路:从第二个数组开始下手,考虑到当前位置,连边,如果之前的边连的点在当前点连的目标点的后面,就会产生一个点,也就是说统计一下之前有多少个点的目标点在目前这个点的目标点后面,树状数组处理一下

 #include <bits/stdc++.h>

 using namespace std;

 #define N 100010
#define ll long long int t, n; int a[N], b[N];
int id[N]; int arr[N]; inline int lowbit(int x)
{
return x & (-x);
} inline void update(int x, int val)
{
for (int i = x; i <= n; i += lowbit(i))
arr[i] += val;
} inline int sum(int x)
{
int ans = ;
for (int i = x; i; i -= lowbit(i))
ans += arr[i];
return ans;
} int main()
{
scanf("%d", &t);
while (t--)
{
scanf("%d", &n);
for (int i = ; i <= n; ++i)
scanf("%d", a + i), id[a[i]] = i;
for (int i = ; i <= n; ++i)
scanf("%d", b + i);
memset(arr, , sizeof arr);
ll ans = ;
for (int i = ; i <= n; ++i)
{
int index = id[b[i]];
ans += sum(n) - sum(index);
update(index, );
}
printf("%lld\n", ans);
}
return ;
}

D:Balloons

水。

 #include <bits/stdc++.h>

 using namespace std;

 int t, n;

 int main()
{
scanf("%d", &t);
while (t--)
{
scanf("%d", &n);
int cnt = ;
for (int i = , num; i <= n; ++i)
{
scanf("%d", &num);
if (num == ) cnt ++;
}
printf("%d\n", n - cnt);
}
return ;
}

E:Maximum Sum

题意:在矩阵中选取部分数,使得权值最大,其中选中的数八个方向的数均不可在选取。、

思路:注意到n很小,可以考虑二进制位表示这个数取不取以及搜索的方法来写。其中遍历每个数的时候,决定这个数能否选取主要取决于这个数的左上角,上方,右上角,左方的数字是否选取。通过一个长度为(1 << 17)的数字表示当前这个数字的左上方到左方的状态。其中第低位表示当前数字的左上方,最高位表示当前数字的左方。在搜索中每个数都有两种状态,取和不取。每次都将当前状态右移一味,去掉没有影响的数字,在添上自己的状态,从而进行下一层的搜索。注意考虑当前数字在这一行第一位和最后一位的情况。最后再添加一点剪枝。

#include<bits/stdc++.h>

using namespace std;

int n;
int ans; int arr[][]; int type[][][ << ]; inline int DFS(int x, int y, int state)
{
if (x == n - && y == n) return ;
if (y == n) return DFS(x + , , state);
if (type[x][y][state] != -) return type[x][y][state];
//not
int res = DFS(x, y + , (state >> ));
//do
if (y == )
{
if (!(state & ( << )) && !(state & ( << ))) res = max(res, DFS(x, y + , ((state >> ) | ( << n))) + arr[x][y]);
}
else if (y == n - )
{
if (!(state & ) && !(state & ( << )) && !(state & ( << n))) res = max(res, DFS(x, y + , ((state >> ) | ( << n))) + arr[x][y]);
}
else
{
if (!(state & ) && !(state & ( << )) && !(state & ( << )) && !(state & ( << n))) res = max(res, DFS(x, y + , ((state >> ) | ( << n))) + arr[x][y]);
}
type[x][y][state] = res;
return res;
} int main()
{
int t;
scanf("%d", &t);
while (t--)
{
memset(type, -, sizeof type);
scanf("%d", &n);
for (int i = ; i < n; ++i)
for (int j = ; j < n; ++j)
scanf("%d", &arr[i][j]);
printf("%d\n", DFS(, , ));
}
return ;
}

F:Working Time

水。

 #include <bits/stdc++.h>

 using namespace std;

 int t, n, m;

 int main()
{
scanf("%d", &t);
while (t--)
{
scanf("%d%d", &n, &m);
int tot = ;
int a, b, c, d;
for (int i = ; i <= n; ++i)
{
scanf("%2d:%2d", &a, &b);
scanf("%2d:%2d", &c, &d);
int aa = a * + b;
int bb = c * + d;
tot += abs(aa - bb);
}
puts(tot >= m * ? "YES" : "NO");
}
return ;
}

G:Hard Equation

留坑。

(拓展BSGS)

H:Cube

水。

 #include <bits/stdc++.h>

 using namespace std;

 int t, a;

 int main()
{
scanf("%d", &t);
while (t--)
{
scanf("%d", &a);
int ans = a / ;
ans = sqrt(ans);
printf("%d\n", ans);
}
return ;
}

I:Circles

题意:给出圆心,半径,求图中阴影部分面积

思路:四个小圆面积 + 大圆面积 - 矩形面积

 #include <bits/stdc++.h>

 using namespace std;

 #define ll long long

 int t;
ll a, b, d; int main()
{
scanf("%d", &t);
while (t--)
{
scanf("%lld%lld%lld", &a, &b, &d);
printf("%.10f\n", (d * d) * 1.0 / );
}
return ;
}

J: Smallest Difference

水。

 #include<bits/stdc++.h>
using namespace std; #define N 10010 int arr[N]; int main()
{
int t;
scanf("%d",&t);
while(t--)
{
memset(arr, ,sizeof arr);
int n;
scanf("%d",&n);
for(int i =;i<=n;++i)
{
int x;
scanf("%d",&x);
arr[x]++;
}
int ans = ;
for(int i = ;i <= ; ++i)
{
ans = max(arr[i] + arr[i + ], ans);
}
printf("%d\n",ans);
}
return ;
}

K:Citations

按题意模拟即可

 #include <bits/stdc++.h>

 using namespace std;

 int t, n;

 string s;

 string author, title, journal, volume, number, pages, year;

 inline void Init()
{
author.clear();
title.clear();
journal.clear();
volume.clear();
number.clear();
pages.clear();
year.clear();
} inline void work(string &ans)
{
bool flag = false;
for (int i = , len = s.size(); i < len; ++i)
{
if (s[i] == '{')
{
flag = true;
continue;
}
if (s[i] == '}') return;
if (flag == false) continue;
ans += s[i];
}
return;
} inline bool Find(string t)
{
if (t.size() > s.size()) return false;
for (int i = , len = t.size(); i < len; ++i)
{
if (s[i] != t[i]) return false;
}
return true;
} inline void work_author()
{
bool flag = false;
bool fi = false;
int cnt = ;
for (int i = , len = s.size(); i < len; ++i)
{
if (s[i] == '{')
{
flag = true;
continue;
}
if (s[i] == '}') return;
if (isalpha(s[i]) && flag)
{
if (fi == false)
{
if(cnt) author += ", ";
author += s[i];i++;
author += s[i];
author += ". ";
while (s[i] != ' ') i++;
fi = true;
}
else
{
author += s[i];
while (s[i] != ',') i++;
cnt++;
fi = false;
}
}
}
} int main()
{
cin.tie();
cout.tie();
ios::sync_with_stdio(false);
cin >> t;
while (t--)
{
cin >> n;
while (n--)
{
Init();
getline(cin, s);
while (getline(cin, s))
{
if (s == "}") break;
if (Find("author")) work_author();
else if (Find("title")) work(title);
else if (Find("journal")) work(journal);
else if (Find("volume")) work(volume);
else if (Find("number")) work(number);
else if (Find("year")) work(year);
else if (Find("pages")) work(pages);
else continue;
}
cout << author << ". " << title << ". " << journal << ". " << year << ";" << volume << "(" << number << "):" << pages << ".\n";
}
}
}

赛后总结:

  • 考虑数据中是否有特殊点会影响答案
  • 模拟题请考虑更多细节
  • 很多东西可以多考虑一点,比如给出的两个数,按题意是需要有大小关系,但是数据不一定保证其大小关系

ACM ICPC, JUST Collegiate Programming Contest (2018) Solution的更多相关文章

  1. ACM ICPC, Amman Collegiate Programming Contest (2018) Solution

    Solution A:Careful Thief 题意:给出n个区间,每个区间的每个位置的权值都是v,然后找长度为k的区间,使得这个区间的所有位置的权值加起来最大,输出最大权值, 所有区间不重叠 思路 ...

  2. ACM ICPC, Damascus University Collegiate Programming Contest(2018) Solution

    A:Martadella Stikes Again 水. #include <bits/stdc++.h> using namespace std; #define ll long lon ...

  3. ACM International Collegiate Programming Contest, Tishreen Collegiate Programming Contest (2018) Syria, Lattakia, Tishreen University, April, 30, 2018

    ACM International Collegiate Programming Contest, Tishreen Collegiate Programming Contest (2018) Syr ...

  4. German Collegiate Programming Contest 2018​ B. Battle Royale

    Battle Royale games are the current trend in video games and Gamers Concealed Punching Circles (GCPC ...

  5. German Collegiate Programming Contest 2018​ C. Coolest Ski Route

    John loves winter. Every skiing season he goes heli-skiing with his friends. To do so, they rent a h ...

  6. ICPC — International Collegiate Programming Contest Asia Regional Contest, Yokohama, 2018–12–09 题解

    目录 注意!!此题解存在大量假算法,请各位巨佬明辨! Problem A Digits Are Not Just Characters 题面 题意 思路 代码 Problem B Arithmetic ...

  7. [ACM International Collegiate Programming Contest, Amman Collegiate Programming Contest (2018)]

    https://codeforces.com/gym/101810 A. Careful Thief time limit per test 2.5 s memory limit per test 2 ...

  8. 2019.04.04 第二次训练 【ACM International Collegiate Programming Contest, JUST Collegiate Programming Contest (2018)】

    题目链接:https://codeforces.com/gym/101853 A: ✅ B: (二分图匹配) https://blog.csdn.net/qq_41997978/article/det ...

  9. Gym - 101810H ACM International Collegiate Programming Contest (2018)

    bryce1010模板 http://codeforces.com/gym/101810 #include <bits/stdc++.h> using namespace std; #de ...

随机推荐

  1. 查看用户信息:w

    w命令有两个用途: (1) 用于查看当前系统负载(2) 用于查看当前登录用户的行为和信息,执行这个命令可以得知当前登入系统的用户有哪些人,以及他们正在执行哪些程序 [root@localhost ~] ...

  2. windows下配置VisualSVN Server服务器

    下载安装文件: 服务端安装文件:VisualSVN-Server-1.6.2 客户端安装文件:TortoiseSVN-1.5.5.14361-win32-svn-1.5.4 上面是我使用的版本. 在V ...

  3. 什么是SQL注入式攻击和如何防范?

    什么是SQL注入式攻击? 所谓SQL注入式攻击,就是攻击者把SQL命令插入到Web表单的输入域或页面请求的查询字符串,欺骗服务器执行恶意的SQL命令.在某些表单中,用户输入的内容直接用来构造(或者影响 ...

  4. JS-倒计时效果

    团购-限时抢 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www. ...

  5. linux下查看服务器软件的编译参数

    1.nginx编译参数: your_nginx_dir/sbin/nginx -V 2.apache编译参数: cat your_apache_dir/build/config.nice 3.php编 ...

  6. 如何设置Eclipse工作区默认编辑宽度

    1)打开Window  => Preferences窗口 2)打开Formatter属性页从Java => CodeStyle => Formatter 3) 单击New创建一个自己 ...

  7. a Javascript library for training Deep Learning models

    w强化算法和数学,来迎接机器学习.神经网络. http://cs.stanford.edu/people/karpathy/convnetjs/ ConvNetJS is a Javascript l ...

  8. 解决Uploadify 3.2上传控件加载导致的GET 404 Not Found问题

    http://www.uploadify.com/forum/#/discussion/7329/uploadify-v3-bug-unecessary-request-when-there-is-n ...

  9. Django - 路由层(URLconf)

    一.django 静态文件配置 /mysite1/settings.py STATIC_URL = '/static/' STATICFILES_DIRS = [ os.path.join(BASE_ ...

  10. Buy Tickets---poj2828(线段树)

    题目链接:http://poj.org/problem?id=2828 题意就是有n个x y每次都是把y放到x位置,如果x位置有数,则把该位置之后的数往后放一位: [题解]: 线段树节点中保存这一段中 ...