首页 > 代码库 > SDUT月赛

SDUT月赛

A题:点击打开链接

题意:一颗树上最初有n个苹果,晚上就会变成2*n,然后会有人来摘,摘完后剩下 (2*n)%m 然后如此循环,问会不会有一天出现苹果为0;

思路:如果不会出现肯定会出现周期,用哈希判剩余的苹果数是否出现过。

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <string>
#include <cctype>
#include <vector>
#include <cstdio>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>
#define maxn 1000060
#define _ll __int64
#define ll long long
#define INF 0x3f3f3f3f
#define Mod 1000000007
#define pp pair<int,int>
#define ull unsigned long long
#define max(x,y) ( ((x) > (y)) ? (x) : (y) )
#define min(x,y) ( ((x) > (y)) ? (y) : (x) )
using namespace std;
int n,m,vis[1000005];
int main()
{
    while(scanf("%d%d",&n,&m)!=EOF)
	{
		memset(vis,0,sizeof(vis));
		int ok=1;
		vis[n]=1;n*=2;
		while(n%m)
		{
			n%=m;n*=2;
			if(!vis[n])
			{
				vis[n]=1;
			}
			else
			{
				ok=0;
				break;
			}
		}
		if(ok)puts("Yes");
		else puts("No");
	}
    return 0;
}

B题:点击打开链接

题意:给一个数列,求 ai-aj 最大 ,(i<j)

思路:预处理+枚举 。首先逆向求出 区间[i+1,n] 内的最小值dp[i],然后正向枚举求max(a[i]-dp[i])

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <string>
#include <cctype>
#include <vector>
#include <cstdio>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>
#define maxn 1000060
#define _ll __int64
#define ll long long
#define INF 0x3f3f3f3f
#define Mod 1000000007
#define pp pair<int,int>
#define ull unsigned long long
#define max(x,y) ( ((x) > (y)) ? (x) : (y) )
#define min(x,y) ( ((x) > (y)) ? (y) : (x) )
using namespace std;
int n,m,dp[1000005],a[1000005];
int main()
{
    while(scanf("%d",&n)!=EOF)
	{
		for(int i=1;i<=n;i++)
			scanf("%d",a+i);
		dp[n]=a[n];
		for(int i=n-1;i>=1;i--)
			dp[i]=min(a[i],dp[i+1]);
		int ans=-INF;
		for(int i=1;i<n;i++)
		ans=max(ans,a[i]-dp[i+1]);
		printf("%d\n",ans);

	}
    return 0;
}

C题:点击打开链接

题意:n个点,其中有一个起点和终点,现在要从起点遍历除起点和终点外的所有点然后再回到终点,求最小时间。

思路:先求出起点到所有点的最短路diss[] ,和终点到所有点的最短路 dise[] ,枚举所有点,因为是所有的路径同时进行,枚举 max(diss[i]+dise[i]) 最大的那条路都走完了的话,最短的肯定也走完了(比赛的时候没时间了。。A题卡了太久了  没做完)

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <string>
#include <cctype>
#include <vector>
#include <cstdio>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>
#define maxn 1000060
#define _ll __int64
#define ll long long
#define INF 0x3f3f3f3f
#define Mod 1000000007
#define pp pair<int,int>
#define ull unsigned long long
using namespace std;
int n,m,diss[1005],dise[1005],st,sink;
bool vis[1005];
vector < pp > eg[100005];
void spfas(int src)
{
    queue <int> Q;
    memset(vis,0,sizeof(vis));
    memset(diss,INF,sizeof(diss));
    diss[src]=0;Q.push(src);
    while(!Q.empty())
    {
        int u=Q.front();Q.pop();
        vis[u]=0;
        for(int i=0;i<eg[u].size();i++)
        {
            int v=eg[u][i].first;
            int w=eg[u][i].second;
            if(diss[v]>diss[u]+w)
            {
                diss[v]=diss[u]+w;
                if(!vis[v])
                {
                    vis[v]=1;
                    Q.push(v);
                }
            }
        }
    }
}
void spfae(int src)
{
    queue <int> Q;
    memset(vis,0,sizeof(vis));
    memset(dise,INF,sizeof(dise));
    dise[src]=0;Q.push(src);
    while(!Q.empty())
    {
        int u=Q.front();Q.pop();
        vis[u]=0;
        for(int i=0;i<eg[u].size();i++)
        {
            int v=eg[u][i].first;
            int w=eg[u][i].second;
            if(dise[v]>dise[u]+w)
            {
                dise[v]=dise[u]+w;
                if(!vis[v])
                {
                    vis[v]=1;
                    Q.push(v);
                }
            }
        }
    }
}
int main()
{
	int T,u,v,c,cas=1;
	scanf("%d",&T);
    while(T--)
	{
		scanf("%d%d",&n,&m);
		for(int i=0;i<=n;i++)
			eg[i].clear();
		while(m--)
		{
			scanf("%d%d%d",&u,&v,&c);
			eg[u].push_back(make_pair(v,c));
			eg[v].push_back(make_pair(u,c));
		}
		scanf("%d%d",&st,&sink);
		spfas(st);spfae(sink);
		int ans=-INF;
		for(int i=0;i<n;i++)
			ans=max(ans,diss[i]+dise[i]);
		printf("Case #%d: %d\n",cas++,ans);
	}
    return 0;
}

D题:点击打开链接

脑残题,找规律会出现循环节

题目大意是A说:why are you so diao B说:你猜 A说:你猜我猜不猜 B说:你猜我猜不猜你猜不猜 A说:。。

给出 A或B 和 他们说的第几句话 问这句话的字母缩写。

然后在脑中模拟一下这个脑残对话就ok了。。(ps不要一直往后想 会疯掉的)

贴脑残代码

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <string>
#include <cctype>
#include <vector>
#include <cstdio>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>
#define maxn 1000060
#define _ll __int64
#define ll long long
#define INF 0x3f3f3f3f
#define Mod 1000000007
#define pp pair<int,int>
#define ull unsigned long long
#define max(x,y) ( ((x) > (y)) ? (x) : (y) )
#define min(x,y) ( ((x) > (y)) ? (y) : (x) )
using namespace std;
int main()
{
	char s[4];int n;
    while(scanf("%s %d",s,&n)!=EOF)
	{

		if(s[0]=='A')
		{
			if(n==1)
				puts("Waysd");
			else
			{
				string x="Ncwcbc";
				for(int i=3;i<=n;i++)
					x+="ncbcwcbc";
				cout<<x<<endl;
			}
		}
		else
		{
			if(n==1)
				puts("Nc");
			else
			{
				string y="Nc";
				for(int i=2;i<=n;i++)
					y+="wcbcncbc";
				cout<<y<<endl;
			}
		}
	}
    return 0;
}

E题:点击打开链接

题意:n杯水中有一杯是有毒的,毒性在一周内发作,现在要在一周内测出哪杯水有毒,问至少需要多少只小白鼠。

貌似这个问题网上比较火,二进制问题,给n杯水按二进制编号从1编到n ,然后取出二进制1代表有毒0代表无毒,分别取出二进制下末为是1的杯子编号的水混合,(依次是倒数第二位为1,倒数第三。。)假设二进制最多有x个位,然后派x只小白鼠来喝这些混合水,死了的是1,没死的是0,从左到右写下来然后转换成10进制就是对应有毒的杯子的编号。。

说白了这题就是求n转化成二进制有几位。

贴个java脑残代码。。

import java.io.*;
import java.util.*;
import java.math.*;
public class Main {

	public static void main(String[] args) {
		Scanner in=new Scanner(System.in);
		String a;
		while(in.hasNext()){
			a=in.next();
			BigInteger b=new BigInteger(a,10);
			System.out.println(b.toString(2).length());
		}
	}
}

F题:点击打开链接

裸拓扑排序,注意要字典序答案。

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <string>
#include <cctype>
#include <vector>
#include <cstdio>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>
#define maxn 1000060
#define _ll __int64
#define ll long long
#define INF 0x3f3f3f3f
#define Mod 1000000007
#define pp pair<int,int>
#define ull unsigned long long
#define max(x,y) ( ((x) > (y)) ? (x) : (y) )
#define min(x,y) ( ((x) > (y)) ? (y) : (x) )
using namespace std;
int ans[30005],in[30005],tot,n,m;
vector <int> eg[100005];
void top_sort()
{
	priority_queue <int,vector<int>,greater<int> > s;tot=0;
	for(int i=1;i<=n;i++)
	{
		if(in[i]==0)
			s.push(i);
	}
	while(!s.empty())
	{
		int u=s.top();s.pop();
		ans[tot++]=u;
		for(int i=0;i<eg[u].size();i++)
		{
			int v=eg[u][i];
			in[v]--;
			if(in[v]==0)
				s.push(v);
		}
	}
	for(int i=0;i<tot;i++)
		if(i!=tot-1)
		printf("%d ",ans[i]);
	    else
		printf("%d\n",ans[i]);
}
int main()
{
	int u,v;
    while(scanf("%d%d",&n,&m)!=EOF)
	{
		memset(in,0,sizeof(in));
		for(int i=1;i<=n;i++)
			eg[i].clear();
		while(m--)
		{
			scanf("%d%d",&u,&v);
			eg[u].push_back(v);
			in[v]++;
		}
		top_sort();
	}
    return 0;
}


SDUT月赛