[考试总结]noip模拟57
这场又是和cqbz联考的。
赛前:
教练: 明天还是联考,和cqbz,都是一些初三高一的...
我(心理):原来是初三高一的啊,那还行吧。。
教练:都是银牌水平...
我:。。。
然后他们就有julao阿克了。。。
但是今天的题目本身并不是很难
2A
这个玩意模拟不就行了。。。
但是细节比较多,一不小心就挂没了。
比方说:YES
打成 Yes
(lxb)
#include<bits/stdc++.h>
using std::cout; using std::endl;
#define try(i,a,b) for(register signed i=a;i<=b;++i)
#define throw(i,a,b) for(register signed i=a;i>=b;--i)
#define go(i,x) for(register signed i=head[x],y=edge[i].ver;i;i=edge[i].next,y=edge[i].ver)
namespace xin_io
{
#define file(a) FILE *FI = freopen(#a".in","r",stdin); FI = freopen(#a".out","w",stdout)
#define sb(x) cout<<#x" = "<<x<<' '
#define jb(x) cout<<#x" = "<<x<<endl
#define debug cout<<"debug"<<endl
#define gc() p1 == p2 and (p2 = (p1 = buf) + fread(buf,1,1<<20,stdin),p1 == p2) ? EOF : *p1++
char buf[1<<20],*p1 = buf,*p2 = buf; int ak; typedef long long ll; typedef unsigned long long ull;
#define scanf ak = scanf
}
using namespace xin_io;static const int maxn = 1e6+10,inf = 1e9+7;const ll llinf = 1e18+7;
#define int long long
auto max = [](int x,int y) -> int{return x > y ? x : y;}; auto min = [](int x,int y) -> int{return x < y ? x : y;};
namespace xin
{
char s[maxn];
std::string com;
int a[10];
inline short main()
{
file(ip);
scanf("%s",s+1);
int l = strlen(s + 1);
int p = 1;
try(i,1,4)
{
while(!isdigit(s[p])) p++;
while(isdigit(s[p]))
{
a[i] = a[i] * 10 + (s[p] - '0');
p ++;
if(a[i] > (int)(1e17)) a[i] = 256;
}
// jb(p);
// cout<<a[i]<<' ';
}
bool ok = 1;
int len = 0;
auto ws = [](int x) -> int
{
int ret = 0;
while(x) ret ++,x /= 10;
return ret;
};
auto div = [=](int i) -> std::string
{
std::string temp; temp.clear();
register int x = a[i] > 255 ? 255 : a[i];
if(!x) temp.push_back('0');
while(x)
{
temp.push_back(x % 10 + '0');
x /= 10;
}
std::reverse(temp.begin(),temp.end());
return temp;
};
com.push_back(' ');
try(i,1,4)
{
com += div(i);
if(i xor 4) com += '.';
}
// cout<<com<<endl;
try(i,1,(int)com.size()-1)
if(com[i] != s[i]) {ok = 0;break;}
// sb(l); jb(com.size());
if(l != (int)com.size()-1) ok = 0;
if(ok)
{
cout<<"YES"<<endl;
// try(i,1,l) cout<<s[i];
}
else
{
cout<<"NO"<<endl;
try(i,1,4)
{
cout<<(a[i] > 255 ? 255 : a[i]);
if(i xor 4) cout<<'.';
}
}
return 0;
}
}
signed main() {return xin::main();}
2B
这个东西是个贪心。
我们每次选能消的就消。
然而我不会证明。。。
#include<bits/stdc++.h>
using std::cout; using std::endl;
#define try(i,a,b) for(register signed i=a;i<=b;++i)
#define throw(i,a,b) for(register signed i=a;i>=b;--i)
#define go(i,x) for(register signed i=head[x],y=edge[i].ver;i;i=edge[i].next,y=edge[i].ver)
namespace xin_io
{
#define file(a) FILE *FI = freopen(#a".in","r",stdin); FI = freopen(#a".out","w",stdout)
#define sb(x) cout<<#x" = "<<x<<' '
#define jb(x) cout<<#x" = "<<x<<endl
#define debug cout<<"debug"<<endl
#define gc() p1 == p2 and (p2 = (p1 = buf) + fread(buf,1,1<<20,stdin),p1 == p2) ? EOF : *p1++
#define scanf ak = scanf
char buf[1<<20],*p1 = buf,*p2 = buf; int ak; typedef long long ll; typedef unsigned long long ull;
class xin_stream{public:template<typename type>inline xin_stream &operator >> (type &s)
{
register int f = 0;s = 0; register char ch = gc();
while(!isdigit(ch)) {f |= ch == '-'; ch = gc();}
while( isdigit(ch)) s = (s << 1) + (s << 3) + (ch xor 48),ch = gc(); return s = f ? -s : s,*this;
}}io;
}
using namespace xin_io;static const int maxn = 1e6+10,inf = 1e9+7;const ll llinf = 1e18+7;
auto max = [](int x,int y) -> int{return x > y ? x : y;}; auto min = [](int x,int y) -> int{return x < y ? x : y;};
namespace xin
{
int a[maxn],n,ans = inf;
char s[maxn];
bool vis[maxn];
auto nxt = [](int x) -> int
{
if(!x) return 0;
x++;
while(vis[x]) x ++;
if(x > n) return 0;
return x;
};
auto check = []() -> int
{
int ret = 0;
try(i,1,n) ret += !vis[i];
return ret;
};
void dfs()
{
// if(!pan()) return;
// try(i,1,n) if(!vis[i]) cout<<s[i]<<' '; cout<<endl;
ans = min(ans,check());
std::vector < int > vec;
vec.clear();
int p = 1;
if(vis[p]) p = nxt(p);
while(1)
{
if(s[p] == 'A' and s[nxt(p)] == 'P')
{
// sb(p); jb(nxt(p));
vec.push_back(p);
break;
}
else if(s[p] == 'P' and s[nxt(p)] == 'P')
{
vec.push_back(p);//,sb(p),jb(nxt(p));
// try(i,1,n) cout<<vis[i]<<' ';cout<<endl;
break;
}
p = nxt(p);
// sb(p); jb(nxt(p));
// try(i,1,n) if(vis[i]) cout<<i<<' '; cout<<endl;
if(!p) break ;
// jb(p);
}
if(!vec.size()) return ;
for(auto v : vec)
{
int pre = nxt(v);
vis[v] = 1; vis[nxt(v)] = 1;
dfs();
vis[v] = 0; vis[pre] = 0;
}
}
inline short main()
{
// file(apstr);
freopen("apstr.in","r",stdin); freopen("apstr.out","w",stdout);
scanf("%s",s+1);
ans = n = strlen(s + 1);
// jb(nxt(1));
// jb(nxt(0));
dfs();
cout<<ans<<endl;
return 0;
}
}
signed main() {return xin::main();}
3C
这个题目的最主要的难度实在 \(3\) 情况。
因为太菜然而没有想出来怎么处理。
我们可以每一个点上维护一个 bitset
,那么我们就枚举每次输入的 \(k\) 个类。
然后看其中两个有没有祖先上的交集,并且这两个不成为祖孙关系。
然后记得不合法的操作要舍弃。。
#include<bits/stdc++.h>
using std::cout; using std::endl;
#define try(i,a,b) for(register signed i=a;i<=b;++i)
#define throw(i,a,b) for(register signed i=a;i>=b;--i)
#define go(i,x) for(register signed i=head[x],y=edge[i].ver;i;i=edge[i].next,y=edge[i].ver)
namespace xin_io
{
#define file(a) FILE *FI = freopen(#a".in","r",stdin); FI = freopen(#a".out","w",stdout)
#define sb(x) cout<<#x" = "<<x<<' '
#define jb(x) cout<<#x" = "<<x<<endl
#define debug cout<<"debug"<<endl
#define gc() p1 == p2 and (p2 = (p1 = buf) + fread(buf,1,1<<20,stdin),p1 == p2) ? EOF : *p1++
#define scanf ak = scanf
char buf[1<<20],*p1 = buf,*p2 = buf; int ak; typedef long long ll; typedef unsigned long long ull;
}
using namespace xin_io;static const int maxn = 1e6+10,inf = 1e9+7;const ll llinf = 1e18+7;
auto max = [](int x,int y) -> int{return x > y ? x : y;}; auto min = [](int x,int y) -> int{return x < y ? x : y;};
namespace xin
{
int n;
std::string s,m,st[maxn/1000+1];
std::map<std::string,int>vis;
std::bitset<maxn/1000>bit[maxn/1000];
int cnt = 0;
inline short main()
{
file(class);
// freopen("class.in","r",stdin); freopen("class.out","w",stdout);
std::ios::sync_with_stdio(false);
std::cin >> n;
s = ";";
vis[s] = 1;
try(cse,1,n)
{
bool ok = 1;
std::cin >> s; m = s;
if(vis[m]) ok = 0;
std::cin >> s;
int k = 0;
while(st[k][0] != ';')
{
std::cin >> st[++k];
if(!vis[st[k]]) ok = 0;
}
k --;
if(ok)
{
try(i,1,k) try(j,i+1,k)
if(ok)
{
int x = vis[st[i]],y = vis[st[j]];
if((bit[x] & bit[y]).count() and !bit[x][y] and !bit[y][x])
{ok = 0;break;}
}
}
if(ok)
{
vis[m] = ++cnt;
try(i,1,k)
{
int x = vis[m];
bit[x] |= bit[vis[st[i]]];
bit[x][vis[st[i]]] = 1;
}
}
puts(ok ? "ok" : "greska");
}
// for(auto v : vis) cout<<v.first<<endl;
return 0;
}
}
signed main() {return xin::main();}
4D
写的是一个暴力。
就是每次用 dfs
统计答案,就是这样:
#define go(i,x) for(register signed i=head[x],y=edge[i].ver;i;i=edge[i].next,y=edge[i].ver)
void dfs(int x)
{
vis[x] = 1; scn ++;
go(i,x)
{
if(ji[y]) {scb++; continue;}
scm ++;
if(!vis[y]) dfs(y);
}
}
然后每次进行 topo
删点。
之后就可以 \(Ac\) ,但是我的代码常数似乎有点大,然后要看评测机心情。。。
%: pragma GCC optimize(2)
#include<bits/stdc++.h>
using std::cout; using std::endl;
#define try(i,a,b) for(register signed i=a;i<=b;++i)
#define throw(i,a,b) for(register signed i=a;i>=b;--i)
#define go(i,x) for(register signed i=head[x],y=edge[i].ver;i;i=edge[i].next,y=edge[i].ver)
namespace xin_io
{
#define file(a) FILE *FI = freopen(#a".in","r",stdin); FI = freopen(#a".out","w",stdout)
#define sb(x) cout<<#x" = "<<x<<' '
#define jb(x) cout<<#x" = "<<x<<endl
#define debug cout<<"debug"<<endl
#define gc() p1 == p2 and (p2 = (p1 = buf) + fread(buf,1,1<<20,stdin),p1 == p2) ? EOF : *p1++
char buf[1<<20],*p1 = buf,*p2 = buf; int ak; typedef long long ll; typedef unsigned long long ull;
class xin_stream{public:template<typename type>inline xin_stream &operator >> (type &s)
{
register int f = 0;s = 0; register char ch = gc();
while(!isdigit(ch)) {f |= ch == '-'; ch = gc();}
while( isdigit(ch)) s = (s << 1) + (s << 3) + (ch xor 48),ch = gc(); return s = f ? -s : s,*this;
}}io;
}
using namespace xin_io;static const int maxn = 2e6+10,inf = 1e9+7;const ll llinf = 1e18+7;
#define int long long
auto max = [](int x,int y) -> int{return x > y ? x : y;}; auto min = [](int x,int y) -> int{return x < y ? x : y;};
namespace xin
{
class xin_edge{public:int next,ver;}edge[maxn];
int head[maxn],rp = 1;
auto add = [](int x,int y) -> void{edge[++rp].next = head[x]; edge[rp].ver = y;head[x] = rp;};
int n,m,a,b,c,k,scn,scm,scb,cnt;
int ind[maxn];
bool ji[maxn],vis[maxn];
std::pair<int,int>ans = std::make_pair(-llinf,-llinf);
std::queue<int>q;
void dfs(int x)
{
vis[x] = 1; scn ++;
go(i,x)
{
if(ji[y]) {scb++; continue;}
scm ++;
if(!vis[y]) dfs(y);
}
}
inline short main()
{
file(kdgraph);
io >> n >> m >> a >> b >> c;
try(i,1,m)
{
register int x,y; io >> x >> y;
add(x,y); add(y,x);
ind[x] ++; ind[y] ++;
}
auto topo = [](int k) -> void
{
while(q.size())
{
register int x = q.front(); q.pop();
ji[x] = 1; ++ cnt;
go(i,x) if(!ji[y])
{
ind[y] --;
if(ind[y] == k) q.push(y);
}
}
};
try(i,1,n) if(ind[i] == 0) cnt++,ji[i] = 1;
int jsq = 0;
try(k,1,n)
{
try(i,1,n) if(!ji[i] and !vis[i])
{
scn = scm = scb = 0;
dfs(i);
scm >>= 1;
int ret = a * scm - b * scn + c * scb;
// sb(scn); sb(scm); sb(scb); jb(ret);
if(ret >= ans.second) ans.first = k,ans.second = ret;
// cout<<"k = "<<k<<" jsq = "<<++jsq<<endl;
}
memset(vis,0,sizeof(bool) * (n + 1));
try(i,1,n) if(ind[i] == k) q.push(i);
// sb(n); jb(cnt);
topo(k);
if(cnt == n or k == n) {cout<<ans.first<<' '<<ans.second<<endl; return 0;}
}
return 0;
}
}
signed main() {return xin::main();}