zoukankan      html  css  js  c++  java
  • EZ 2018 05 01 NOIP2018 模拟赛(十一)

    莫名其妙暴涨Rating

    其实题目都挺好挺简单的,但是越简单就越容易ZZ

    不理解问什么第一题这么多人找环

    不过T2是真心细节题,T3太难了

    题目戳这里

    T1

    仔细分析题意发现那个交换规则就是废话,如果有方案的话相当于直接把邮票给别人,因此就很显然了

    把人和邮票分开来,由每个人向自己想要的邮票建一条边。最后看一看是否存在完美匹配即可

    懒得写网络流了,然后匈牙利哲学复杂度,O(能过)

    CODE

    #include<cstdio>
    #include<cstring>
    using namespace std;
    const int N=10005;
    struct edge
    {
    	int to,next;
    }e[N<<1];
    int from[N],head[N],n,m,cnt,ans,x,y;
    bool vis[N];
    inline void read(int &x)
    {
    	x=0; char ch=getchar();
    	while (ch<'0'||ch>'9') ch=getchar();
    	while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
    }
    inline void add(int x,int y)
    {
    	e[++cnt].to=y; e[cnt].next=head[x]; head[x]=cnt;
    }
    inline bool find(int now)
    {
    	for (register int i=head[now];i!=-1;i=e[i].next)
    	if (!vis[e[i].to-n])
    	{
    		vis[e[i].to-n]=1;
    		if (!from[e[i].to-n]||find(from[e[i].to-n]))
    		{
    			from[e[i].to-n]=now;
    			return 1;
    		}
    	}
    	return 0;
    }
    int main()
    {
    	//freopen("A.in","r",stdin); freopen("A.out","w",stdout);
    	register int i;
    	while (scanf("%d%d",&n,&m)!=EOF)
    	{
    		memset(head,-1,sizeof(head));
    		memset(e,-1,sizeof(e));
    		memset(from,0,sizeof(from));
    		for (cnt=0,i=1;i<=m;++i)
    		read(x),read(y),add(x,y+n);
    		for (ans=0,i=1;i<=n;++i)
    		memset(vis,0,sizeof(vis)),ans+=find(i);
    		puts(ans^n?"NO":"YES");
    	}
    	return 0;
    }
    

    T2

    粗看上去很难的一道题,其实很。。。。。。

    由于要让所有长度为k的子串都是一些字符串的字串,因此我们想到把字符串的所有长度为k-1的字串hash后当成一个点,然后相邻的字串对应的点之间连一条边

    然后,如果有环则可以无限刷下去

    所以我们先判环,再找出最长路

    但是SPFA判环的复杂度是O(哲学),而且这里边权都是1,因此我们可以用基于广搜的拓扑排序来搞,复杂度O(n)

    不过这里最难写的其实还是hash,这里不像写自然溢出因为涉及到减法,所以hash成一个longlong的数然后开个map就好了

    CODE

    #include<cstdio>
    #include<cstring>
    #include<map>
    using namespace std;
    typedef long long LL;
    const int N=100005,seed=2333;
    struct edge
    {
    	int to,next;
    }e[N];
    map <LL,int> hash;
    LL pow[N];
    int head[N],q[N],step[N],ru[N],tot,cnt,n,k,ans;
    char s[N];
    inline void add(int x,int y)
    {
    	e[++cnt].to=y; e[cnt].next=head[x]; head[x]=cnt; ++ru[y];
    }
    inline int max(int a,int b)
    {
    	return a>b?a:b;
    }
    inline void clear(void)
    {
    	hash.clear();
    	memset(head,-1,sizeof(head));
    	memset(e,-1,sizeof(e));
    	memset(ru,0,sizeof(ru));
    	memset(step,0,sizeof(step));
    	ans=cnt=tot=0; --k;
    }
    inline int topo(void)
    {
    	register int i; int H=0,T=0;
    	for (i=1;i<=tot;++i) 
    	if (!ru[i]) step[i]=k,q[++T]=i;
    	while (H<T)
    	{
    		int now=q[++H]; ans=max(ans,step[now]);
    		for (i=head[now];i!=-1;i=e[i].next)
    		if (!(--ru[e[i].to])) step[e[i].to]=max(step[e[i].to],step[now]+1),q[++T]=e[i].to;
    	}
    	return T;
    }
    int main()
    {
    	//freopen("CODE.in","r",stdin); freopen("CODE.out","w",stdout);
    	register int i;
    	for (pow[0]=1,i=1;i<N;++i) pow[i]=pow[i-1]*seed;
    	while (scanf("%d%d",&n,&k)!=EOF)
    	{
    		clear();
    		while (n--)
    		{
    			scanf("%s",s+1); int len=strlen(s+1);
    			LL now=0,last;
    			for (i=1;i<=k;++i)
    			now=now*seed+s[i];
    			if (!hash[now]) hash[now]=++tot;
    			for (last=now,i=k+1;i<=len;++i)
    			{
    				now=(last-pow[k-1]*s[i-k])*seed+s[i];
    				if (!hash[now]) hash[now]=++tot;
    				add(hash[last],hash[now]); last=now;
    			}
    		}
    		if (!k) { puts("INF"); continue; }
    		if (topo()!=tot) { puts("INF"); continue; } else printf("%d
    ",ans);
    	}
    	return 0;
    }
    

    T3

    这道题考试的时候也没多想,直接码了一个暴力

    然后事实证明这是最明智的选择

    对于这种需要大量数学基础的题目连组合数都看不出来的我还是原地爆炸算了

    标算在此

    爆搜30CODE

    #include<cstdio>
    #include<vector>
    using namespace std;
    const int N=1000005,mod=1000000007;
    vector <int> r[N];
    int n,m,t,a[N],x,y,f[N],s[N],ans;
    inline char tc(void)
    {
    	static char fl[100000],*A=fl,*B=fl;
    	return A==B&&(B=(A=fl)+fread(fl,1,100000,stdin),A==B)?EOF:*A++;
    }
    inline void read(int &x)
    {
    	x=0; char ch=tc();
    	while (ch<'0'||ch>'9') ch=tc();
    	while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=tc();
    }
    inline int max(int a,int b)
    {
    	return a>b?a:b;
    }
    inline bool check(void)
    {
    	for (register int i=1;i<=m;++i)
    	{
    		int res=0;
    		for (register int j=0;j<r[i].size();++j)
    		res+=f[r[i][j]];
    		if (res!=s[i]) return 0;
    	}
    	return 1;
    }
    inline void DFS(int now)
    {
    	if (now>n) { if (check()) ans=ans+1==mod?0:ans+1; return; }
    	for (register int i=0;i<=a[now];++i)
    	{
    		f[now]=i;
    		DFS(now+1);
    	}
    }
    int main()
    {
    	//freopen("C.in","r",stdin); freopen("C.out","w",stdout);
    	register int i,j;
    	read(n); read(m);
    	for (i=1;i<=m;++i)
    	{
    		read(x);
    		for (j=1;j<=x;++j)
    		read(y),r[i].push_back(y);
    		for (read(s[i]),j=0;j<r[i].size();++j)
    		a[r[i][j]]=max(a[r[i][j]],s[i]);
    	}
    	for (read(t),i=1;i<=t;++i)
    	read(x),read(y),a[x]=y;
    	DFS(1);
    	printf("%d",ans);
    	return 0;
    }
    
  • 相关阅读:
    log4net Appenders
    cnblogs 安家了
    log4net 资源索引贴
    Log2Console A Generic Log Viewer (for Log4Net, NLog...)
    [前端技术]如何加深对JavaScipt中的Math.ceil() 、Math.floor() 、Math.round() 三个函数的理解
    msiexec 命令使用文档
    “安装和部署”文章索引
    一句SQL实现获取自增列操作
    MsChart 部署遇到的一点问题
    [Asp.net]ZipHelper 在线压缩解压帮助类(SharpZipLib组件实现)
  • 原文地址:https://www.cnblogs.com/cjjsb/p/8998413.html
Copyright © 2011-2022 走看看