总的来说,这场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;
}
离散化搞一下就可以了。
离散化可以用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;
}