zoukankan      html  css  js  c++  java
  • 2014上海全国邀请赛题解 HDOJ 5090-5099

    HDOJ 5090

    水题。从小到大排序,能够填充达到符合条件的。先填充好。填充之后进行调整。

    传送门:点击打开链接

    #include <cstdio>
    #include <cmath>
    #include <queue>
    #include <map>
    #include <vector>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    
    const int MAXN = 1e2+10;
    int t, n, k, ia[MAXN];
    
    int main()
    {
        scanf("%d", &t);
        while(t--)
        {
            scanf("%d%d", &n, &k);
            bool flag = true;
            for(int i=1; i<=n; ++i)
            {
                scanf("%d", ia+i);
            }
            sort(ia+1, ia+n+1);
            for(int i=1; i<=n; ++i)
            {
                if(i < ia[i])
                {
                    flag = false;
                    break;
                }
                if(i == ia[i])
                {
                    continue;
                }
                if(0 == (i-ia[i])%k)
                {
                    ia[i] = i;
                }
                else
                {
                    int tp = 1;
                    for(int j=i+1; j<=n; ++j)
                    {
                        if(0 == (j-ia[i])%k)
                        {
                            ia[i] = j;
                            tp = 0;
                            --i;
                            break;
                        }
                    }
                    if(tp)
                    {
                        flag = false;
                        break;
                    }
                }
                sort(ia+1, ia+n+1);
            }
            printf("%s
    ", flag ?

    "Jerry" : "Tom"); } return 0; }


    HDOJ 5092

    题意:每行取一个数。使总和最小,取了mp[i][j]之后,仅仅能在该点左下,正下。右下三个位置里面取下一个点。记录路径。要注意尽量靠右。

    分析:一个典型的dp

    传送门:点击打开链接

    #include <cstdio>
    #include <cmath>
    #include <queue>
    #include <map>
    #include <vector>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    
    const int MAXN = 1e2+10;
    const int INF = 0x7fffffff;
    int t, m, n, dp[MAXN][MAXN];
    int s[MAXN][MAXN], mp[MAXN][MAXN], icase = 1;
    
    void output(int i, int j)
    {
        if(0 == i)
        {
            return ;
        }
        if(1 == s[i][j])
        {
            output(i-1, j-1);
            printf("%d ", j-1);
        }
        else if(2 == s[i][j])
        {
            output(i-1, j);
            printf("%d ", j);
        }
        else if(3 == s[i][j])
        {
            output(i-1, j+1);
            printf("%d ", j+1);
        }
    }
    
    int main()
    {
        scanf("%d", &t);
        while(t--)
        {
            scanf("%d%d", &n, &m);
            memset(dp, 0, sizeof(dp));
            memset(mp, 0, sizeof(mp));
            memset(s, 0, sizeof(s));
            for(int i=1; i<=n; ++i)
            {
                for(int j=1; j<=m; ++j)
                {
                    scanf("%d", &mp[i][j]);
                }
            }
            for(int i=1; i<=m; ++i)
            {
                dp[1][i] = mp[1][i];
            }
            for(int i=2; i<=n; ++i)
            {
                for(int j=1; j<=m; ++j)
                {
                    int mn = INF;
                    if(j>=2 && dp[i-1][j-1] <= mn)
                    {
                        mn = dp[i-1][j-1];
                        s[i][j] = 1;
                    }
                    if(dp[i-1][j] <= mn)
                    {
                        mn = dp[i-1][j];
                        s[i][j] = 2;
                    }
                    if(j<=m-1 && dp[i-1][j+1] <= mn)
                    {
                        mn = dp[i-1][j+1];
                        s[i][j] = 3;
                    }
                    dp[i][j] = mn + mp[i][j];
                }
            }
            int mn = INF, id = 0;
            for(int i=1; i<=m; ++i)
            {
                if(dp[n][i] <= mn)
                {
                    mn = dp[n][i];
                    id = i;
                }
            }
    /*
            printf("%d
    ", mn);
            for(int i=1; i<=n; ++i)
            {
                for(int j=1; j<=m; ++j)
                {
                    printf("%d ", dp[i][j]);
                }
                printf("
    ");
            }
    */
            printf("Case %d
    ", icase++);
            output(n, id);
            printf("%d
    ", id);
        }
        return 0;
    }
    

    HDOJ 5093

    分析:二分图。

    队友写的,没细看,贴个队友的代码。之后有空再看。

    传送门:点击打开链接

    代码:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    int match[1260];
    char map[60][60];
    int pic[1260][60];
    int vis[1260];
    int m,n;		
    int nx=0,ny[60],nk=0,flag=0,yvis[60];
    int dp(int now)
    {
    	int i;
    	for(i=0;pic[now][i]!=-1;i++)
    	{
    		int t=pic[now][i];
    		if(vis[t]==1)
    			continue;
    		vis[t]=1;
    		if(match[t]==-1||dp(match[t]))
    		{
    			match[t]=now;
    			return 1;
    		}
    	}
    	return 0;
    }
    int main()
    {
    	//freopen("D:\in.txt","r",stdin);
    	int t,i,j;
    	cin>>t;
    	while(t--)
    	{
    		cin>>m>>n;
    		for(i=0;i<m;i++)
    			scanf("%s",map[i]);
    		memset(yvis,0,sizeof(yvis));
    		for(i=0;i<n;i++)
    			ny[i]=i;
    		nx=nk=0;
    		flag=0;
    		memset(pic,-1,sizeof(pic));
    		for(i=0;i<m;i++)
    		{
    			for(j=0;j<n;j++)
    			{
    				if(map[i][j]=='*')
    				{
    					yvis[j]=1;
    					pic[nx][flag++]=ny[j];
    				}
    				if(map[i][j]=='#')
    				{
    					if(flag)
    					{
    						nx++;
    						flag=0;
    					}
    					if(yvis[j])
    					{
    						ny[j]=n+nk;
    						nk++;
    						yvis[j]=0;
    					}
    				}
    			}
    			if(flag)
    			{
    				nx++;
    				flag=0;
    			}
    		}
    		int ans=0;
    		memset(match,-1,sizeof(match));
    		for(i=0;i<=nx;i++)
    		{
    			memset(vis,0,sizeof(vis));
    			if(dp(i))
    				ans++;
    		}
    		cout<<ans<<endl;
    	}
    }

    HDOJ 5094

    分析:BFS+状压(不然会MLE)。wa点:一个位置可能有几把不同的钥匙。

    传送门:点击打开链接

    #include <cstdio>
    #include <cmath>
    #include <queue>
    #include <map>
    #include <vector>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    
    const int MAXN = 55;
    int n, m, p, k, s, mk[MAXN][MAXN];
    int vis[1<<11][MAXN][MAXN];
    int dir[4][2] = { {-1, 0}, {1, 0}, {0, -1}, {0, 1} };
    struct P
    {
        int x, y, time, key;
    };
    map<int, int> mp;
    
    int BFS()
    {
        memset(vis, 0, sizeof(vis));
        queue<P> que;
        P s; s.x = s.y = 1;
        s.key = s.time = 0;
        if(mk[s.x][s.y])
        {
            s.key = mk[s.x][s.y];
        }
        vis[s.key][s.x][s.y] = 1;
        que.push(s);
        while(!que.empty())
        {
            P u = que.front();
            que.pop();
            if(u.x==n && u.y==m)
            {
                return u.time;
            }
            for(int i=0; i<4; ++i)
            {
                P v;
                v.x = u.x + dir[i][0];
                v.y = u.y + dir[i][1];
                if(v.x<1 || v.x>n || v.y<1 || v.y>m)
                {
                    continue;
                }
                int q = 51*51*51*u.x + 51*51*u.y + 51*v.x + v.y;
                int tp = mp[q];
                if(4e8 == tp)
                {
                    continue;
                }
                if(0 == tp)
                {
                    v.time = u.time + 1;
                    v.key = u.key;
                    if(mk[v.x][v.y] && 0==(mk[v.x][v.y]&u.key))
                    {
                        v.key += mk[v.x][v.y];
                    }
                    if(vis[v.key][v.x][v.y])
                    {
                        continue;
                    }
                    vis[v.key][v.x][v.y] = 1;
                    que.push(v);
                }
                else
                {
                    if(u.key & (1<<tp))
                    {
                        v.time = u.time + 1;
                        v.key = u.key;
                        if(mk[v.x][v.y] && 0==(mk[v.x][v.y]&u.key))
                        {
                            v.key += mk[v.x][v.y];
                        }
                        if(vis[v.key][v.x][v.y])
                        {
                            continue;
                        }
                        vis[v.key][v.x][v.y] = 1;
                        que.push(v);
                    }
                }
            //    printf("%d %d %d %d
    ", v.x, v.y, v.time, v.key);
            }
        }
        return -1;
    }
    
    int main()
    {
        while(~scanf("%d%d%d", &n, &m, &p))
        {
            scanf("%d", &k);
            mp.clear();
            memset(mk, 0, sizeof(mk));
            while(k--)
            {
                int ux, uy, vx, vy, g, hx, hy;
                scanf("%d%d%d%d%d", &ux, &uy, &vx, &vy, &g);
                hx = 51*51*51*ux + 51*51*uy + 51*vx + vy;
                hy = 51*51*51*vx + 51*51*vy + 51*ux + uy;
                if(0 == g) g = 4e8;
                mp[hx] = mp[hy] = g;
            }
            scanf("%d", &s);
            while(s--)
            {
                int x, y, q;
                scanf("%d%d%d", &x, &y, &q);
                mk[x][y] += (1<<q);
            }
            printf("%d
    ", BFS());
        }
        return 0;
    }
    

    HDOJ 5095

    分析:水题,写的时候注意处理-1,0。1就差点儿相同了。还有首位为正。不须要+。

    传送门:点击打开链接

    代码:

    #include <cstdio>
    #include <cmath>
    #include <queue>
    #include <map>
    #include <vector>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    
    typedef long long lint;
    const int MAXN = 20;
    char ch[] = {'p', 'q', 'r', 'u', 'v', 'w', 'x', 'y', 'z'};
    int ia[MAXN], t;
    
    int main()
    {
        scanf("%d", &t);
        while(t--)
        {
            for(int i=0; i<10; ++i)
            {
                scanf("%d", ia+i);
            }
            int first = 1, zero = 1;
            for(int i=0; i<10; ++i)
            {
                if(0 == ia[i])
                {
                    continue;
                }
                zero = 0;
                if(ia[i] < 0)
                {
                    if(-1 == ia[i])
                    {
                        if(i < 9)
                        {
                            printf("-");
                        }
                        else
                        {
                            printf("-1");
                        }
                    }
                    else
                    {
                        printf("%d", ia[i]);
                    }
                    first = 0;
                }
                else
                {
                    if(1 == ia[i])
                    {
                        if(!first)
                        {
                            printf("+");
                        }
                        first = 0;
                        if(i == 9)
                        {
                            printf("1");
                        }
                    }
                    else
                    {
                        if(!first)
                        {
                            printf("+");
                        }
                        first = 0;
                        printf("%d", ia[i]);
                    }
                }
                if(i < 9)
                {
                    printf("%c", ch[i]);
                }
            }
            if(zero) printf("0");
            printf("
    ");
        }
        return 0;
    }
    

    HDOJ 5098

    队友写的,贴个代码。之后补。

    传送门:点击打开链接

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<map>
    #include<algorithm>
    using namespace std;
    char info[1010][1030];
    int need[1010][1010],nn[1010];
    int num[1010];
    int res[1010],ns;   //ns为软件数量,res表示是否要重新启动
    map<string,int> list;
    int dfs(int now)
    {
    	if(num[now]!=-1)
    		return num[now];
    	int ma=0,i;
    	for(i=0;need[now][i]!=-1;i++)
    	{
    		int t=need[now][i];
    		if(res[t])
    			ma=max(ma,dfs(t)+1);
    		else
    			ma=max(ma,dfs(t));
    	}
    	num[now]=ma;
    	return num[now];
    }
    int main()
    {
    	//freopen("D:\in.txt","r",stdin);
    	int t,i,j,count=1;
    	cin>>t;
    	getchar();
    	getchar();
    	while(t--)
    	{
    		memset(info,0,sizeof(info));
    		list.clear();
    		memset(res,0,sizeof(res));
    		i=0;
    		while(gets(info[i]))                     //開始数据处理
    		{
    			if(strlen(info[i])==0)
    				break;
    			j=0;
    			while(info[i][j]!='*'&&info[i][j]!=':')
    				j++;
    			list[string(info[i],j)]=i;
    			if(info[i][j]=='*')
    				res[i]=1;
    			i++;
    		}
    		ns=i;
    		memset(need,-1,sizeof(need));
    		memset(nn,0,sizeof(nn));
    		for(i=0;i<ns;i++)
    		{
    			int s=0;
    			while(info[i][s]!=' '&&s!=strlen(info[i]))
    				s++;
    			int e=s;
    			while(e!=strlen(info[i]))
    			{
    				s=e;
    				e++;
    				while(e!=strlen(info[i])&&info[i][e]!=' ')
    					e++;
    				need[i][nn[i]++]=list[string(info[i]+s+1,e-s-1)];
    			}
    		}                                                               //数据处理结束。need[i]表示i的依赖包,到-1结束
    		memset(num,-1,sizeof(num));
    		int ma=0;
    		for(i=0;i<ns;i++)
    		{
    			if(res[i])
    				ma=max(ma,dfs(i)+1);
    			else
    				ma=max(ma,dfs(i));
    		}
    		printf("Case %d: %d
    ",count++,ma);
    	}
    }

    HDOJ 5099

    分析:水题,字符串比較。

    传送门:点击打开链接

    代码:

    #include <cstdio>
    #include <cmath>
    #include <queue>
    #include <map>
    #include <vector>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    
    const int MAXN = 2e3+10;
    char cha[MAXN], chb[MAXN];
    int t, icase = 1;
    
    int main()
    {
        scanf("%d", &t);
        while(t--)
        {
            scanf("%s%s", cha, chb);
           // puts(cha); puts(chb);
           printf("Case %d: ", icase++);
           if(cha[0] > chb[0])
           {
               printf("> ");
           }
           else if(cha[0] < chb[0])
           {
               printf("< ");
           }
           else
           {
               printf("= ");
           }
           if(cha[1] != chb[1])
           {
               cha[5] = chb[5] = '';
           }
           int ret = strcmp(cha+2, chb+2);
           if(ret > 0)
           {
               printf(">");
           }
           else if(ret < 0)
           {
               printf("<");
           }
           else
           {
               printf("=");
           }
           printf("
    ");
        }
        return 0;
    }
    


  • 相关阅读:
    第10件事 向优秀产品学习的学问
    第9件事 产品定位要解决的6个问题
    第8件事 3步打造产品的独特气质
    Git 从服务器取得最新代码覆盖本地
    Git:代码冲突常见解决方法
    oracle线程数更改
    从Git仓库中恢复已删除的分支、文件或丢失的commit
    Sublime 3114 + 转换GBK方法
    教你快速写出多线程Junit单元测试用例
    Spring中加载xml配置文件的六种方式
  • 原文地址:https://www.cnblogs.com/mfrbuaa/p/5334716.html
Copyright © 2011-2022 走看看