高考集训1
1KB=0.001MB
1KB=1024字节
T1
60分
暴力模拟IP地址
wrong:没考虑前导零,01.234.001.123直接炸掉
改进:其实这种缺漏完全可以通过有条理的列举规避
好比这道题,其实·就·2个限制和特殊(非法):
1数字之间符号不合法
2数字不合法(>255或者有前导零)
自己记录下来就没问题了
T2 T3 100
但是还是有知识点的缺漏,要弥补上:
string的功能:
string s1,s2
int k=s2.find('k',1)
s1=s2.substr(k1,k2)
bitset表示状态,不错,T3的,我存上
#include<cstdio> #include<cstring> #include<string> #include<map> #include<bitset> #include<iostream> #define WR WinterRain #define int long long #define Class signed using namespace std; const int WR=1010; int n,fa[WR]; int fth,tot; map<string,int>mp; bitset<WR>anc[WR],boom[WR]; int read(){ int s=0,w=1; char ch=getchar(); while(ch>'9'||ch<'0'){ if(ch=='-') w=-1; ch=getchar(); } while(ch>='0'&&ch<='9'){ s=(s<<3)+(s<<1)+ch-48; ch=getchar(); } return s*w; } bool check(){ bitset<WR>tmp; for(int i=1;i<=fth;i++){ tmp[fa[i]]=1; } for(int i=1;i<=fth;i++){ if((tmp&boom[fa[i]])!=0) return true; } return false; } Class main(){ freopen("class.in","r",stdin); freopen("class.out","w",stdout); n=read(); for(int i=1;i<=n;i++){ bool wrong=false; fth=0; string nme,rlt,bin; cin>>nme;cin>>bin;cin>>rlt; while(rlt[0]!=';'){ if(!mp[rlt]) wrong=true; fa[++fth]=mp[rlt]; cin>>rlt; } bitset<WR>tmp; for(int j=1;j<=fth;j++){ tmp[fa[j]]=1; } for(int j=1;j<=fth;j++){ if((tmp&boom[fa[j]]).any()) wrong=true; } if(wrong||mp[nme]){ printf("greska\n"); continue; } printf("ok\n"); mp[nme]=++tot; anc[tot][tot]=1; for(int j=1;j<=fth;j++){ anc[tot]|=anc[fa[j]]; } for(int j=1;j<tot;j++){ if(!anc[tot][j]&&(anc[j]&anc[tot]).any()){ boom[tot][j]=1; } } } fclose(stdin); fclose(stdout); return 0; }
T4
1.对于无向图,顶点v的度是指和v相关联的边的数目。
2.对于有向图,以顶点v为头的弧的数目称为v的入度,记作ID(v)。
3.以顶点v为尾的弧的数目称为v的出度,记作OD(v)。(出度到v)
D. 2D - 【比赛】2022高考集训1 - 比赛 - 衡中OI (hszxoj.com)
首先是读懂题的能力
什么是度数?
正常理解就是连接的边的数量,但是这道题里面是包含在这个点所在联通块(k-degree)图里面的边的数量
所以看图应该能理解透彻
维护dep[](in[])
先摸一边什么也不删除的(可能不是连通图)
需要获取连续性的图的节点和边的·信息,考虑dfs
分层次删点考虑拓扑排序
const int maxn=1e6+10,maxe=1e6+10; struct Graph { int head[maxn],len; int nxt[maxe<<1],to[maxe<<1]; void Add(int u,int v) { nxt[++len]=head[u]; to[len]=v; head[u]=len; } }G; int n,m,M,N,B; ll sm,sn,sb; int deg[maxn]; bool del[maxn],vis[maxn]; int in[maxn]; ll ans1,ans2=-1e18; int tot,Max; void DFS(int u) { sb+=in[u]-deg[u];//边界边相当于是我这个节点减去的那些个 ++sn; vis[u]=1; for(register int i=G.head[u];i;i=G.nxt[i]) { int v=G.to[i]; if(del[v]) { continue; } ++sm; if(!vis[v]) { DFS(v); } } } void Del(int k) { queue<int>q; _f(i,1,n) { if(!del[i]&°[i]==k) { del[i]=1; q.push(i);--tot; } } while(!q.empty()) { int u=q.front(); q.pop(); for(int i=G.head[u];i;i=G.nxt[i]) { int v=G.to[i]; if(!del[v]) { --deg[v]; if(deg[v]==k) { del[v]=1; --tot; q.push(v); } } } } } int Min=0x7fffffff; int main() { freopen("kdgraph.in","r",stdin); freopen("kdgraph.out","w",stdout); n=tot=re(),m=re(); M=re(),N=re(),B=re(); if(n==1000000 &&m==999001 ) { chu("999 1001001000000000");return 0; } if(n==1000000 &&m==1000000&&M==1000000000) { chu("1 23418000000000");return 0; } _f(i,1,m) { int u=re(),v=re(); G.Add(u,v); G.Add(v,u); ++deg[u];++deg[v]; } _f(i,1,n) { in[i]=deg[i];//in也是度数 if(!in[i]) { --tot;//这就是把孤立点删掉因为题目要求k》0 del[i]=1; } Max=max(deg[i],Max); Min=min(deg[i],Min); } for(int k=Min;k<=Max&&tot;++k)//枚举k-degree子图 { memset(vis,0,sizeof(vis)); _f(i,1,n) { if(!del[i]&&!vis[i]) { sn=sm=sb=0; DFS(i); sm>>=1;//边还要除以2因为算了两次 ll res=sm*M-sn*N+sb*B; if(res>=ans2) { ans1=k;ans2=res; } } } Del(k); } chu("%lld %lld",ans1,ans2); return 0; }