2014上海全国邀请赛题解 HDOJ 5090-5099

HDOJ 5090

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

传送门:点击打开链接

#include 
#include 
#include 
#include 
#include 
#include 
#include 
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\n", flag ? "Jerry" : "Tom");
    }
    return 0;
}

HDOJ 5092

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

分析:一个典型的dp

传送门:点击打开链接

#include 
#include 
#include 
#include 
#include 
#include 
#include 
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\n", mn);
        for(int i=1; i<=n; ++i)
        {
            for(int j=1; j<=m; ++j)
            {
                printf("%d ", dp[i][j]);
            }
            printf("\n");
        }
*/
        printf("Case %d\n", icase++);
        output(n, id);
        printf("%d\n", id);
    }
    return 0;
}

HDOJ 5093

分析:二分图。

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

传送门:点击打开链接

代码:

#include
#include
#include
#include
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

HDOJ 5094

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

传送门:点击打开链接

#include 
#include 
#include 
#include 
#include 
#include 
#include 
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 mp;

int BFS()
{
    memset(vis, 0, sizeof(vis));
    queue

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<


HDOJ 5095

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

传送门:点击打开链接

代码:

#include 
#include 
#include 
#include 
#include 
#include 
#include 
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("\n");
    }
    return 0;
}

HDOJ 5098

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

传送门:点击打开链接

#include
#include
#include
#include
#include
#include
using namespace std;
char info[1010][1030];
int need[1010][1010],nn[1010];
int num[1010];
int res[1010],ns;   //ns为软件数量,res表示是否要重启
map 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

HDOJ 5099

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

传送门:点击打开链接

代码:

#include 
#include 
#include 
#include 
#include 
#include 
#include 
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] = '\0';
       }
       int ret = strcmp(cha+2, chb+2);
       if(ret > 0)
       {
           printf(">");
       }
       else if(ret < 0)
       {
           printf("<");
       }
       else
       {
           printf("=");
       }
       printf("\n");
    }
    return 0;
}


你可能感兴趣的:(ACM,2014上海全国邀请赛题解,HDOJ)