jzoj_1月26日D组

第一题(手机)

题意:

    这题就是一题模拟,根据给出的9键键盘判断输入一个句子要按的次数,例如a要按1次,b要按2次,z要按4次。

思路:

    用一个数组存下每个字母需要按的次数,之后累加就好了。

代码:

#include<cstdio>
#include<cstring>
using namespace std;
char c;
short cs[27]={0,1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,4,1,2,3,1,2,3,4};
int ans;
int main()
{
	while ((c=getchar())!=EOF)
	{
		ans+=cs[c-96];//累加
		if (c==' ') ans++;//空格加1
	}
    printf("%d",ans);
}

第二题(游戏)

题意:

    king和猫老大玩游戏,首先有n块金子放着,他们每人只能从中拿2的次方个(例如1,2,4,8,16等),他们都会用最好的策略拿金子,谁最后一次可以拿完金子就可以取胜,输出赢家,如果是猫老大,还要输出它第一次最少拿几块金子。

思路:

    刚开始看这题感觉很难,所以没做这题,后面改题时发现了规律:当这n块金子能被3整除时就是king赢,否则就是猫老大赢,最少拿的金子数是n%3,由于数据较大,我们用字符串输入,统计它们各个位数加起来的和,如果能被3整除那这个n就是3的倍数。

代码:

#include<cstdio>
#include<string>
#include<iostream>
using namespace std;
string a,b,c;
int ans;
bool ok(string s)
{
	for (int i=0;i<s.size();i++)
	  ans+=s[i]-48;//累加
	if (ans%3) return true;
	else return false;//判断
}
int main()
{
	cin>>a>>b>>c;//题目要求玩3局
	if (ok(a)) printf("MaoLaoDa will win.\n%d\n",ans%3);
	else printf("King will win.\n");ans=0;
	if (ok(b)) printf("MaoLaoDa will win.\n%d\n",ans%3);
	else printf("King will win.\n");ans=0;
	if (ok(c)) printf("MaoLaoDa will win.\n%d\n",ans%3);
	else printf("King will win.\n");//输出
	
}

第三题(家族)

题意:

    给出一个矩阵,里面要么是空格和*号,要么就是字母,其中字母表示每一个家族,不同的家族不相邻,我们要求共有多少个家族。

思路:

    我做这题时发现输入有点难,所以没做出来,可以用字符输入然后判断是否是字母,是的话就用一个数组存下来,之后用深搜或广搜搜索有几个家族,我这里用的是深搜。

代码:

#include<cstdio>
#include<iostream>
#include<string>
using namespace std;
int o,m,ans,n,t[101][201];
string s;
short dx[4]={0,0,1,-1},
      dy[4]={1,-1,0,0};
void dfs(int x,int y)
{
	t[x][y]=0;//把是连在一起的家族清零
	for (int i=0;i<=3;i++)
	{
		if (x+dx[i]>=1&&x+dx[i]<=n&&y+dy[i]>=1&&y+dy[i]<=m&&t[x+dx[i]][y+dy[i]])
		    dfs(x+dx[i],y+dy[i]);//往四处扩展找连接在一起的家族
	}
}
int main()
{
    scanf("%d",&n);
    getline(cin,s);//这里要读入一个换行符号不然会错
    for (int i=1;i<=n;i++)
    {
    	o=0;
        getline(cin,s);
        for (int j=0;j<s.size();j++)
          if (s[j]>='a'&&s[j]<='z') t[i][++o]=1;
            else t[i][++o]=0;
        
        if (o>m) m=o;//找最长的一条距离来搜索
        
	}
	for (int i=1;i<=n;i++)
	  for (int j=1;j<=m;j++)
	    if (t[i][j]) dfs(i,j),ans++;//如果没有被搜过就统计并从这出发搜索

	printf("%d",ans);  
	    
}

第四题(作业)

题意:

    这题就是一个01背包。

思路:

    先求出光光能受到的最大批评,然后用全部批评的减去最大批评的就是最小批评的。

代码:

#include<cstdio>
int total,n,k,t[100001],p[100001],f[100001];
int max(int x,int y) {return x>y?x:y;}
int main()
{
	scanf("%d",&k);
	scanf("%d",&n);
	for (int i=1;i<=n;i++)
	{
		scanf("%d%d",&t[i],&p[i]);
		total+=p[i];
	}
	for (int i=1;i<=n;i++)
	  for (int j=k;j>=t[i];j--)
	    f[j]=max(f[j-t[i]]+p[i],f[j]);//01背包
    printf("%d",total-f[k]);//求出答案
}



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值