zoukankan      html  css  js  c++  java
  • Codeforces Round #467 (div.2)

    Codeforces Round #467 (div.2)

    我才不会打这种比赛呢
    (其实本来打算打的)
    谁叫它推迟到了(00:05)
    我爱睡觉

    题解

    A. Olympiad

    翻译

    给你若干人的成绩
    让你划定一个分数线
    使得所有不低于这个分数线的人都可以获奖
    但是(0)分的人一定不能得奖
    问你有多少种获奖情况

    题解

    (sort+unique) 然后判断一下最小值是不是(0)就行了

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<set>
    #include<map>
    #include<vector>
    #include<queue>
    using namespace std;
    #define ll long long
    #define RG register
    inline int read()
    {
        RG int x=0,t=1;RG char ch=getchar();
        while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
        if(ch=='-')t=-1,ch=getchar();
        while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
        return x*t;
    }
    int n,a[500];
    int main()
    {
    	n=read();
    	for(int i=1;i<=n;++i)a[i]=read();
    	sort(&a[1],&a[n+1]);
    	int tot=unique(&a[1],&a[n+1])-a-1;
    	if(a[1]==0)tot--;
    	printf("%d
    ",tot);
    	return 0;
    }
    
    

    B. Vile Grasshoppers

    翻译

    给定(p,y)
    (2..y)内找到一个最大值(x)
    使得(x)不能被(2..p)整除
    无解输出(-1)

    题解

    看到范围这么大。
    真是吓死人
    首先考虑一下怎么检查一个值(x)是否可行
    当然不需要枚举(2..p)
    最多只需要枚举到(sqrt x)

    如果有解,要么(p)很小,要么(y)很大
    很容易就可以枚举出来
    如果无解,(p)一定要很接近(y)
    这样不需要枚举多少个数
    复杂度(O(???))

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<set>
    #include<map>
    #include<vector>
    #include<queue>
    using namespace std;
    #define ll long long
    #define RG register
    ll ans=0;
    int main()
    {
    	int p,y;
    	cin>>p>>y;
    	for(int ans=y;ans>p;--ans)
    	{
    		bool fl=true;
    		for(int i=2;i<=p&&i*i<=ans;++i)
    			if(ans%i==0){fl=false;break;}
    		if(fl){cout<<ans<<endl;return 0;}
    	}
    	puts("-1");
    	return 0;
    }
    
    

    C. Save Energy!

    翻译

    有一个人要煮鸡吃
    但是炉子每过(k)分钟就会自动关上
    这个人每过(d)分钟会进厨房,如果炉子关上了他就会打开

    炉子在打开的时候鸡只需要(t)分钟就可以煮熟
    在关上的时候则需要(2t)分钟
    问这个人多久以后可以吃到鸡

    题解

    这题很简单啊
    首先如果(K\%d=0)就不用考虑了
    否则我们一定能够找到一个最小的(x)
    使得(xd>K)
    这样子的话,我们发现开关状态以(xd)循环
    接下来只要分类讨论就行了

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<set>
    #include<map>
    #include<vector>
    #include<queue>
    using namespace std;
    #define ll long long
    #define RG register
    ll K,d,t;
    int main()
    {
    	cin>>K>>d>>t;t*=2;
    	if(K%d==0){cout<<t/2<<endl;return 0;}
    	ll st=K/d+1;
    	ll T=st*d;
    	ll ts=2*K+(T-K);
    	double ans=t/ts*T;t%=ts;
    	if(t<=2*K)ans+=t/2.0;
    	else
    	{
    		ans+=K;
    		t-=2*K;
    		ans+=t;
    	}
    	printf("%.10lf
    ",ans);
    	return 0;
    }
    
    

    D. Sleepy Game

    翻译

    有两个人在玩一个游戏
    有一个棋子和有向图
    一开始棋子在某个位置
    然后两个人轮流走
    谁先走不了谁就输了
    如果超过了(10^6)步则平局
    但是现在第二个人睡觉去了
    两个人都由第一个人操控
    问第一个人能不能赢,如果能输出路径
    否则输出平局或者必败

    题解

    首先考虑能不能赢
    因为能不能赢
    只和到达一个出度为(0)的点的路径的奇偶性有关
    所以用一个(BFS)检查能否以某个奇偶性到达某个点
    如果有出度为(0)的点满足条件,则输出路径

    考虑平局,即能够到达某个环
    第一步检查了能否到达
    这样找到环以后判断一下就好
    如果也不能平局,则必败,输出即可

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<set>
    #include<map>
    #include<vector>
    #include<queue>
    using namespace std;
    #define ll long long
    #define RG register
    #define MAX 120000
    inline int read()
    {
        RG int x=0,t=1;RG char ch=getchar();
        while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
        if(ch=='-')t=-1,ch=getchar();
        while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
        return x*t;
    }
    struct Line{int v,next;}e[MAX*2];
    int h[MAX],cnt=1,n,m,H[MAX],B;
    int dis[MAX][2],zy[MAX][2];
    inline void Add(int u,int v){e[cnt]=(Line){v,h[u]};h[u]=cnt++;}
    void outp(int now,int k,int w)
    {
    	if(!(k==now&&!w))outp(now,zy[k][w],w^1);
    	printf("%d ",k);
    }
    bool bfs(int now)
    {
    	queue<pair<int,int> >Q;
    	Q.push(make_pair(now,0));
    	dis[now][0]=1;
    	while(!Q.empty())
    	{
    		int u=Q.front().first,w=Q.front().second;Q.pop();
    		for(int i=h[u];i;i=e[i].next)
    		{
    			int v=e[i].v;
    			if(dis[v][w^1])continue;
    			zy[v][w^1]=u;
    			dis[v][w^1]=1;
    			Q.push(make_pair(v,w^1));
    		}
    	}
    	for(int i=1;i<=n;++i)
    		if(!H[i]&&dis[i][1])
    		{
    			puts("Win");outp(now,i,1);puts("");
    			return true;
    		}
    	return false;
    }
    int dfn[MAX],low[MAX],tim;
    int S[MAX],top,G[MAX];
    bool vis[MAX];
    bool Ans;
    void Tarjan(int u)
    {
    	S[++top]=u;vis[u]=true;
    	dfn[u]=low[u]=++tim;
    	for(int i=h[u];i;i=e[i].next)
    	{
    		int v=e[i].v;
    		if(!dfn[v])Tarjan(v),low[u]=min(low[u],low[v]);
    		else if(vis[v])low[u]=min(low[u],dfn[v]);
    	}
    	if(dfn[u]==low[u])
    	{
    		int v,size=0;
    		do{v=S[top--];vis[v]=false;G[++size]=v;}while(u!=v);
    		if(size!=1)
    			for(int i=1;i<=size;++i)
    				if(dis[G[i]][0]||dis[G[i]][1])Ans=true;
    	}
    }
    int main()
    {
    	n=read();m=read();
    	for(int i=1;i<=n;++i)
    	{
    		H[i]=read();
    		for(int j=1;j<=H[i];++j)Add(i,read());
    	}
    	B=read();
    	if(bfs(B))return 0;
    	for(int i=1;i<=n;++i)if(!dfn[i])Tarjan(i);
    	if(Ans)puts("Draw");
    	else puts("Lose");
    	return 0;
    }
    
    

    E. Lock Puzzle

    翻译

    给定一个串(s)和目标串(s')

    你每次都可以执行一个(shift)操作

    执行(shift(x))

    假设原来的串是(s=AB)

    那么,现在的串变为了(B^RA)

    其中,(B)的长度等于(x)

    说白点,就是把后(x)个字符翻转后,放在字符串的最前面

    (举个例子,原来是(ababc) ,执行(shift(3))后,变为了(cbaab)

    执行操作的次数不能超过(6100)

    无解输出(-1)

    题解

    我们假设前面已经匹配好了(i-1)

    现在匹配第(j)

    那么,现在当前串中找到一个和目标位置相同的字符,位置是(pos)

    然后考虑(shift)操作

    当然,只需要执行(shift(n-pos),shift(1),shift(n))三次操作就行了

    我们假设当前串是(AcB)其中(c=s[pos])

    (shift(n-pos))之后(B^RAc)

    (shift(1))之后(cB^RA)

    (shift(n))之后(A^RBc)

    这样的话,我们发现后面的位置就不会再变化了

    而每次我们都把当前的目标字符给挪到了最后一个位置

    这样执行(3n)次操作之后就可以得到目标串了

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<set>
    #include<map>
    #include<vector>
    #include<queue>
    using namespace std;
    #define ll long long
    #define RG register
    #define MAX 5000
    int n,a[26],b[26];
    char s[MAX],ss[MAX];
    char s1[MAX],s2[MAX];
    vector<int> ans;
    void shift(char *s,int x)
    {
    	int t1=0,t2=0;
    	for(int i=n-x+1;i<=n;++i)s2[++t2]=s[i];
    	reverse(&s2[1],&s2[t2+1]);
    	for(int i=1;i<=n-x;++i)s1[++t1]=s[i];
    	for(int i=1;i<=x;++i)s[i]=s2[i];
    	for(int i=1;i<=t1;++i)s[i+t2]=s1[i];
    	ans.push_back(x);
    }
    int main()
    {
    	scanf("%d",&n);
    	scanf("%s",s+1);
    	scanf("%s",ss+1);
    	for(int i=1;i<=n;++i)a[s[i]-97]++,b[ss[i]-97]++;
    	for(int i=0;i<26;++i)if(a[i]!=b[i]){puts("-1");return 0;}
    	for(int i=1;i<=n;++i)
    	{
    		int pos;
    		for(int j=1;j<=n;++j)
    			if(s[j]==ss[i]){pos=j;break;}
    		shift(s,n-pos);shift(s,1);shift(s,n);
    	}
    	printf("%d
    ",(int)(ans.size()));
    	for(int i=0;i<ans.size();++i)
    		printf("%d ",ans[i]);
    	return 0;
    }
    
    
  • 相关阅读:
    和2018年年初做管理系统的不同(vuex)
    项目中使用package-lock.json锁版本问题
    沟通协作:避免犯低级错误,开发前沟通清楚所有细节
    学会学习:高效学习方式(使用vscode-snippet有感)
    关于学习,避免没必要的熬夜的思考
    pc端布局的一点思考
    学习掌握一个新东西
    要想有价值,首先要乐于去解决每一个问题
    problem: 记一次聊天框的表情包弹框不显示的找问题过程
    abp-159,js最理想的继承——寄生组合式继承
  • 原文地址:https://www.cnblogs.com/cjyyb/p/8475908.html
Copyright © 2011-2022 走看看