# NEERC训练实录

## 2017-2018 ACM-ICPC, NEERC, Northern Subregional Contest

A. Auxiliary Project

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
using namespace std;
int n;
int main() {
freopen("auxiliary.in", "r", stdin);
freopen("auxiliary.out", "w", stdout);
int i, j, k;
scanf("%d", &n);
if(n%3 == 0) printf("%d\n", n/3*7);
else if(n%3 == 1) printf("%d\n", (n/3-1)*7+4);
else printf("%d\n", n/3*7+1);
return 0;
}


B. Boolean Satis ability

C. Consonant Fencity

$2^17$枚举所有情况再算答案

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
using namespace std;
const int Maxn = 1000010;
char s[Maxn];
int n;
bool v[26];
int num[26], l;
int mp[26][26];
int main() {
freopen("consonant.in", "r", stdin);
freopen("consonant.out", "w", stdout);
int i, j, k;
scanf("%s", s+1);
n = strlen(s+1);
v['a'-'a'] = v['e'-'a'] = v['i'-'a'] = v['o'-'a'] = v['u'-'a'] = v['w'-'a'] = v['y'-'a'] = true;
l = 0;
for(i = 1; i < 26; i++) if(!v[i]) num[i] = l++;
for(i = 2; i <= n; i++){
if(!v[s[i]-'a'] && !v[s[i-1]-'a']) mp[num[s[i]-'a']][num[s[i-1]-'a']]++;
}
int ans = 0, res = 0;
for(i = 1; i < 1<<l; i++){
int ret = 0;
for(j = 0; j < l; j++){
for(k = 0; k < l; k++){
if((i&(1<<j) && !(i&(1<<k))) || (!(i&(1<<j)) && i&(1<<k))) ret += mp[j][k];
}
}
if(ret > ans) ans = ret, res = i;
}
for(i = 1; i <= n; i++){
if(res&(1<<num[s[i]-'a'])) s[i] += 'A'-'a';
printf("%c", s[i]);
}
return 0;
}


*D. Dividing Marbles

nike0good的blog，有空研究

E. Equal Numbers

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
using namespace std;
const int Maxn = 1000010;
int sum[Maxn], n;
int a[Maxn], al, b[Maxn], bl;
int f[Maxn];
int _min(int x, int y) { return x < y ? x : y; }
int main() {
freopen("equal.in", "r", stdin);
freopen("equal.out", "w", stdout);
int i, j, k;
scanf("%d", &n);
for(i = 1; i <= n; i++){
int x;
scanf("%d", &x);
sum[x]++;
}
int ss = 0;
for(i = 1; i <= 1000000; i++){
if(sum[i] > 0){
bool bk = false;
for(j = i+i; j <= 1000000; j += i){
if(sum[j] > 0){ bk = true; break; }
}
if(bk == true) a[++al] = sum[i];
b[++bl] = sum[i];
ss++;
}
}
memset(f, 63, sizeof(f)); f[0] = ss;
sort(a+1, a+al+1);
int su = 0;
for(i = 1; i <= al; i++){
su += a[i];
f[su] = _min(f[su], ss-i);
}
sort(b+1, b+bl+1);
su = 0;
for(i = 1; i <= bl; i++){
su += b[i];
f[su] = _min(f[su], ss-i+1);
}
for(i = 0; i <= n; i++){
if(i) f[i] = _min(f[i], f[i-1]);
printf("%d%c", f[i], i==n?'\n':' ');
}
return 0;
}


*F. Fygon 2.0

*G. Grand Test

dfs，用反祖边覆盖树边，如果一条树边被覆盖了两次，把这两条反祖边拿出来

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;
const int Maxn = 100010;
struct node {
int x, y, next;
}a[Maxn<<1]; int first[Maxn], len;
void ins(int x, int y) {
len++;
a[len].x = x; a[len].y = y;
a[len].next = first[x]; first[x] = len;
}
int n, m;
int fa[Maxn], bo[Maxn]; bool bk, insta[Maxn];
int dfn[Maxn], id;
int ansk1, ansk2, ansx, ansy;
void dfs(int x) {
if(!bk) return;
dfn[x] = ++id; insta[x] = true;
for(int k = first[x]; k && bk; k = a[k].next){
int y = a[k].y;
if(y == fa[x]) continue;
if(!dfn[y]){
fa[y] = x; bo[y] = 0;
dfs(y);
} else if(insta[y]){
int p = x;
while(p != y){
if(bo[p]){
bk = false;
ansk1 = bo[p];
ansk2 = k;
break;
}
bo[p] = k;
p = fa[p];
}
}
}
insta[x] = false;
}
vector <int> vec[Maxn];
queue <int> q;
int pre[Maxn], ans[Maxn], ansl;
int main() {
freopen("grand.in", "r", stdin);
freopen("grand.out", "w", stdout);
int i, j, k;
int T;
scanf("%d", &T);
while(T--){
scanf("%d%d", &n, &m);
len = 0; for(i = 1; i <= n; i++) first[i] = 0;
for(i = 1; i <= m; i++){
int x, y;
scanf("%d%d", &x, &y);
ins(x, y); ins(y, x);
}
for(i = 1; i <= n; i++) dfn[i] = 0; id = 0;
bk = true;
for(i = 1; i <= n && bk; i++) if(!dfn[i]) fa[i] = 0, dfs(i);
if(bk == true){ printf("-1\n"); continue; }
for(i = 1; i <= n; i++) vec[i].clear();
vec[a[ansk1].x].push_back(a[ansk1].y); vec[a[ansk1].y].push_back(a[ansk1].x);
vec[a[ansk2].x].push_back(a[ansk2].y); vec[a[ansk2].y].push_back(a[ansk2].x);
int p = a[ansk1].x;
while(p != a[ansk1].y){
vec[p].push_back(fa[p]); vec[fa[p]].push_back(p);
p = fa[p];
}
p = a[ansk2].x;
while(p != a[ansk2].y){
if(bo[p] != ansk1) vec[p].push_back(fa[p]), vec[fa[p]].push_back(p);
p = fa[p];
}
ansx = ansy = 0;
for(i = 1; i <= n; i++){
if(vec[i].size() == 3){
if(!ansx) ansx = i;
else { ansy = i; break; }
}
}
for(i = 1; i <= n; i++) pre[i] = -1;
printf("%d %d\n", ansx, ansy);
pre[ansx] = 0;
q.push(ansx);
while(!q.empty()){
int x = q.front(); q.pop();
for(i = 0; i < vec[x].size(); i++){
int y = vec[x][i];
if(pre[y] == -1){
if(y == ansy){
ansl = 0; ans[++ansl] = ansy;
for(j = x; j; j = pre[j]) ans[++ansl] = j;
printf("%d ", ansl);
for(j = ansl; j >= 1; j--) printf("%d%c", ans[j], j==1?'\n':' ');
continue;
}
pre[y] = x;
q.push(y);
}
}
}
}
return 0;
}


*H. Hidden Supervisors

dp根选与不选的最大匹配，发现$f_{i,1}-f_{i,0}\leq 1$

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;
const int Maxn = 100010;
const int inf = 0x7fffffff;
vector <int> vec[Maxn];
int fa[Maxn], n;
int f[Maxn][2], num[Maxn], size[Maxn];
void dfs(int x) {
size[x] = 1;
if(vec[x].size() == 0) return;
int ret1 = -inf; f[x][0] = 0;
for(int i = 0; i < vec[x].size(); i++){
int y = vec[x][i];
dfs(y);
size[x] += size[y];
if(!vec[y].size()){
if(0 > ret1) ret1 = 0, num[x] = y;
} else {
f[x][0] += f[y][1];
if(f[y][0]-f[y][1] > ret1) ret1 = f[y][0]-f[y][1], num[x] = y;
}
}
f[x][1] = f[x][0]+ret1+1;
}
queue <int> q, qu;
void dfs2(int x) {
for(int i = 0; i < vec[x].size(); i++){
int y = vec[x][i];
if(y == num[x]) continue;
if(!vec[y].size()) q.push(y);
else dfs2(y);
}
for(int i = 0; i < vec[num[x]].size(); i++){
int y = vec[num[x]][i];
if(!vec[y].size()) q.push(y);
else dfs2(y);
}
}
struct lnode {
int x, p;
lnode (int x = 0, int p = 0) : x(x), p(p) {}
bool operator<(const lnode &A) const { return p > A.p; }
}list[Maxn]; int l;
int main() {
freopen("hidden.in", "r", stdin);
freopen("hidden.out", "w", stdout);
int i, j, k;
scanf("%d", &n);
for(i = 2; i <= n; i++){
scanf("%d", &fa[i]);
if(fa[i]) vec[fa[i]].push_back(i);
}
for(i = 1; i <= n; i++){
if(!fa[i]) dfs(i);
}
int ans = 0;
if(vec[1].size() == 0) q.push(1);
else {
ans += f[1][1];
dfs2(1);
}
for(i = 2; i <= n; i++){
if(!fa[i]){
if(!vec[i].size()) qu.push(i);
else if(f[i][0] < f[i][1]) ans += f[i][1], fa[i] = 1, dfs2(i);
else list[++l] = lnode(i, size[i]-2*f[i][0]-1);
}
}
sort(list+1, list+l+1);
for(i = 1; i <= l; i++){
if(q.empty() && !qu.empty()){
int x = qu.front();
fa[x] = 1;
q.push(x); qu.pop();
}
if(!q.empty()){
int x = q.front(); q.pop();
fa[list[i].x] = x; ans++;
ans += f[list[i].x][0];
for(j = 0; j < vec[list[i].x].size(); j++){
int y = vec[list[i].x][j];
if(!vec[y].size()) q.push(y);
else dfs2(y);
}
} else {
fa[list[i].x] = 1;
ans += f[list[i].x][1];
dfs2(list[i].x);
}
}
while(!q.empty() && !qu.empty()){
int x = q.front(), y = qu.front(); q.pop(); qu.pop();
fa[y] = x; ans++;
}
while(!qu.empty()){
int x = qu.front(); qu.pop();
fa[x] = 1;
if(!qu.empty()){
int y = qu.front(); qu.pop();
fa[y] = x; ans++;
}
}
printf("%d\n", ans);
for(i = 2; i <= n; i++) printf("%d%c", fa[i], i==n?'\n':' ');
}


I. Intelligence in Perpendicularia

*J. Joker

K. Kotlin Island

L. Little Difference

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#define LL long long
using namespace std;
const LL sx = 1e18+100;
LL n;
struct lnode {
LL x, i, j;
lnode (LL x = 0, LL i = 0, LL j = 0) : x(x), i(i), j(j) {}
}list[1000010]; LL l;
LL mul(LL x, LL y) {
if(x > sx/y) return sx;
x *= y;
if(x > sx) return sx;
return x;
}
LL qpow(LL x, LL k) {
LL ret = 1;
while(k){
if(k&1) ret = mul(ret, x);
x = mul(x, x);
k >>= 1;
}
return ret;
}
bool check(LL x, LL i, LL j) {
return mul(qpow(x, i), qpow(x+1, j)) <= n;
}
int main() {
freopen("little.in", "r", stdin);
freopen("little.out", "w", stdout);
LL i, j, k;
scanf("%I64d", &n);
if((n&(-n)) == n){ printf("-1\n"); return 0; }
for(i = 0; i <= 59; i++){
LL p, o;
if(p = qpow(2, i) > n) break;
for(j = 1; j <= 31; j++){
if(mul(p, qpow(3, j)) > n) break;
LL L = 2, R = n, ret;
while(L <= R){
LL mid = L+R>>1;
if(check(mid, i, j)) ret = mid, L = mid+1;
else R = mid-1;
}
if(mul(qpow(ret, i), qpow(ret+1, j)) == n) list[++l] = lnode(ret, i, j);
}
}
printf("%I64d\n", l);
for(i = 1; i <= l; i++){
printf("%I64d", list[i].i+list[i].j);
while(list[i].i--) printf(" %I64d", list[i].x);
while(list[i].j--) printf(" %I64d", list[i].x+1);
printf("\n");
}
return 0;
}


posted @ 2017-12-26 15:28  Ra1nbow  阅读(324)  评论(0编辑  收藏  举报