BestCoder Round #42

27 篇文章 0 订阅

总的来说,这场BsetCoder还是挺简单的,看上去一般都有思路,第四题没人写出来,前三题写出来的人一大片,手速赛哦。

题目链接: 5232 Shaking hands 

有中文题意。

水题,统计出给出的0-1矩阵1的个数加上2*n就是答案

AC代码:

#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<sstream>
#include<fstream>
#include<vector>
#include<map>
#include<stack>
#include<list>
#include<set>
#include<queue>
#define LL long long
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1 | 1
using namespace std;
const int maxn=100005,inf=1<<29;
int dir[][2]={ {0,1},{-1,0},{0,-1},{1,0},{-1,1},{-1,-1},{1,-1},{1,1}};
int n,m,t;
int main()
{
    while(~scanf("%d",&n))
    {
        int ans=2*n;
        for(int i=0;i<n;i++)
            for(int j=0;j<n;j++)
        {
            scanf("%d",&m);
            ans+=m;
        }
        printf("%d\n",ans);
    }
    return 0;
}

   
题目链接 5233 Gunner II

离散化搞一下就可以了。

离散化可以用map

#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<sstream>
#include<fstream>
#include<vector>
#include<map>
#include<stack>
#include<list>
#include<set>
#include<queue>
#define LL long long
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1 | 1
using namespace std;
const int maxn=1000005,inf=1<<29;
int dir[][2]={ {0,1},{-1,0},{0,-1},{1,0},{-1,1},{-1,-1},{1,-1},{1,1}};
int n,m,t,a[maxn],vis[maxn];
vector<int>G[maxn];
int main()
{
    while(~scanf("%d%d",&n,&m))
    {
        map<int,int>mp;
        int cnt=1;
        for(int i=1;i<=n;i++) G[i].clear();//清空
        for(int i=1;i<=n;i++) scanf("%d",&a[i]);//读取数据
        for(int i=1;i<=n;i++)
        {
            t=a[n-i+1];//倒过来存,那么离枪越近的越迟进入动态数组,这样做是为了方便以后的删除操作
            if(mp[t]==0) mp[t]=cnt++;//由于出现的数比较大,故映射为比较小的数,方便开数组保存
            G[mp[t]].push_back(n-i+1);//存入动态数组
        }
        for(int i=1;i<=m;i++)
        {
            scanf("%d",&t);
            int id=mp[t];//到映射后的值对应的数组里找
            if(G[id].size()==0) printf("-1\n");//没有元素
            else
            {
                printf("%d\n",G[id][G[id].size()-1]);//输出对应数组的最后一个元素,也就是离枪最近的鸟
                G[id].pop_back();//删除末端元素
            }
        }
    }
    return 0;
}

5234 Happy birthday

类似背包的DP

设dp[i][j][p]:达到点(i,j)背包容量为p时获得的最大值

考虑从上面走过来的路径,如果不选择点(i,j)则m1=dp[i-1][j][p],选择点(i,j)则m3=dp[i-1][j][p-a[i][j]]+a[i][j];

考虑从左边走过来的路径,如果不选择点(i,j)则m2=dp[i][j-1][p],选择点(i,j)则m4=dp[i][j-1][p-a[i][j]]+a[i][j];

dp[i][j][p]=max(m1,m2,m3,m4)

下面是AC代码:

#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<sstream>
#include<fstream>
#include<vector>
#include<map>
#include<stack>
#include<list>
#include<set>
#include<queue>
#define LL long long
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1 | 1
using namespace std;
const int maxn=125;
int n,m,k;
int dp[maxn][maxn][maxn];
int a[maxn][maxn];
int main()
{
    while(~scanf("%d%d%d",&n,&m,&k))
    {
        memset(dp,0,sizeof(dp));
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
            scanf("%d",&a[i][j]);
        int ans=0;
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=m;j++)
            {
                for(int p=k;p>=0;p--)//0-1背包则从大到小
                {
                    int m1=dp[i-1][j][p];//不选当前的且取从上面走过来的路径
                    int m2=dp[i][j-1][p];//不选当前的且取从左边走过来的路径
                    int m3=0;
                    if(a[i][j]<=p) m3=dp[i][j-1][p-a[i][j]]+a[i][j];//选当前的且取从上面走过来的路径
                    int m4=0;
                    if(a[i][j]<=p) m4=dp[i-1][j][p-a[i][j]]+a[i][j];//选当前的且取从左边走过来的路径
                    int m5=max(m1,m2),m6=max(m3,m4);
                    dp[i][j][p]=max(m5,m6);//取上面四种情况的最大值
                    ans=max(ans,dp[i][j][p]);//更新最优解
                }
            }
        }
        printf("%d\n",ans);
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值