中南大学新生入门赛题解(部分)

三秒内找出唐可可

题目描述

给出唐可可的字符画,你需要在3秒内找出她在另一幅字符画中出现的地方。

要求逐字符严格匹配。

输入格式

第一行空格隔开n和m表示唐可可的字符画有n行m列。

接下来是n行每行m个字符给出唐可可字符画。

接着一行空格隔开u和v表示另一幅字符画有u行v列。

接下来是u行每行v个字符给出另一幅字符画。

输出格式

一行空格隔开的a和b,表示另一幅字符画中出现的唐可可的左上角坐标即第a行b列处,注意两者都从1开始计算。

如果存在多个这样的a和b,你得输出首先a最小,其次b最小的答案。输入保证一定存在至少一组这样的解。

输入输出样例

输入
3 3
@@@
QWQ
_/
9 9
@@@@@@@@@
QMQOWOQvQ
_/_/_/
@@@@@@@@@
QwQQWQQxQ
_/_/_/
@@@@@@@@@
OxooxOQWQ
_/_/_/
输出
4 4

题解:

第一个要注意的就是读入地图,用getline 每行读取,同时记得数字输入再输入字符串需要吞回车,然后暴力枚举即可。

#include<bits/stdc++.h>
using namespace std;
vector<string>s;
vector<string>mp;
char ss[55][55];
int main()
{   int n, m;
	cin >> n >> m;
	getchar();
	for (int i = 1; i <= n; i++)
	{
		string ss;
		getline(cin, ss);//读入每行 可能写丑了
		s.push_back(ss);
	 }
	int nn, mm;
	cin >> nn >> mm;
	getchar();//吞回车
	for (int i = 1; i <= nn; i++)
	{
		string ss;
		getline(cin, ss);
		mp.push_back(ss);
	}
	int resi, resj,flag=0,flag1=1;//flag 标注是否找到, flag1标注每一回是否跳出主要用来break
	for (int i = 0; i < nn; i++)
	{
		for (int j = 0; j < mm; j++)
		{
			flag1 = 1;
			for (int z = 0; z < n; z++)
			{
				for (int k = 0; k < m; k++)
				{
					if (i + z >= nn || j + k >= mm || s[z][k] != mp[i + z][j + k])
					{   
						flag1 = 0;
						break;
					}
					if (z == n - 1 && k == m - 1)
					{
						flag = 1;
						resi = i, resj = j;
						break;
					}
				}if (flag||!flag1)break;
			}if (flag)break;
		}if (flag)break;
	}
	cout<<resi+1 << " " << resj+1 << endl;//下标从1 开始
}

重装系统

题目描述

由于机房电脑太老了, 受不了日常卡顿的 ggccggcc 和 liqingliqing 决定将机房电脑重装系统,但是他们不会这些操作。于是在夜夜的帮助下,他们重装好了 1 号机。现在要将 1 号机重装好的系统传给其他电脑。机房里有一些数据线,一条数据线可以连接两台电脑,相连的两台电脑可以在 1 分钟内传完数据,即一个重装好了系统的电脑可以用一分钟通过数据线将系统传给另一台电脑。

当前数据传完后,数据线可以插到其他电脑上。可以不考虑插拔数据线的时间。一台电脑上最多可以同时插一条数据线。

现在一共有 nn 台电脑,要将1号机的系统传给其他的 n-1n−1 台电脑。当前他们一共有 kk 条数据线,ggccggcc 和 liqingliqing 想要知道将整个机房都重装上系统最少花费多少分钟。

题解:

如果没有k的限制那么每次都会翻倍即为 2i当这个值大于k时,每次至多增加k,分开求即可

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll n, k;
int t;
int main()
{   
	cin >> t;
	while (t--)
	{
		cin >> n >> k;
		ll ts = 1,res=0;//ts为当前已经修好的机器
		if (n == 1)printf("0\n" );
		else {

			while (ts <= k&&ts<n)//如果比k小或者所有机器修好了
			{
				ts *= 2;//比k小翻倍
				res++;
			}
			n -= ts;
			if (n <= 0)printf("%lld\n", res);
			else
			{
				res += n / k;
				if (n % k !=0)res++;//剩下稳定修k个,有余数多加一次
				printf("%lld\n", res);
			}
		}
	}
}

C语言作业题

题意:t次询问每次询问区间的回文素数,先用欧拉筛预处理出所有的素数,依次判断是不是回文数,由于t次询问(t =1e5)所以要用前缀和处理

#include<iostream>
using namespace std;
int book[10000005], prim[10000005], cnt,sum[10000005];//book用来欧拉筛 prim放素数 sum的下标代表既是素数又是回文数的数
void get_prime(int n)//欧拉筛
{
    for (int i = 2; i <= n; i++)
    {    
        if (book[i] == 0)
            prim[cnt++] = i;
        for (int j = 0; prim[j] <= n / i; j++)
        {
            book[prim[j] * i] = 1;
            if (i % prim[j] == 0)break;
        }
    }
}
int  check(long num)//判断回文数
{
    long r = 0, temp = num;
    while (num)
    {
        r = r * 10 + num % 10;
        num = num / 10;
    }
    if (r == temp)
        return 1;
    else
        return 0;
}

int main()
{
    int n,q;
    cin >> n>>q;
    get_prime(n);
    for (int i = 0; i < cnt; i++)
    {
        if (check((long)prim[i]))sum[prim[i]]++;
    }
    for (int i = 1; i <= n; i++)
        sum[i] = sum[i - 1] + sum[i];
    while (q--)
    {
        int l, r;
        scanf("%d%d", &l, &r);
        printf("%d\n", sum[r] - sum[l - 1]);
    }

    
}

信用点/疯狂星期四

题目描述

如图:

花20000000可以让LexBurner的账号解封,得到19260817点社会信用。
花2000000可以让杏回归,得到18741515点社会信用。
花200000可以给东雪莲上10个月总督,得到11451419点社会信用。
花20000可以让女孩不用在厕所生孩,得到8101919点社会信用。
花2000可以去华东理工大学买一副耳机,得到889464点社会信用。
花500可以尽情嘴臭一顿€€£,得到500000点社会信用~~,并被禁赛1年~~。
花200可以让985学生买一副VR眼镜在厕所求导,得到364364点社会信用。
花20可以愉快地度过一个疯狂星期四,得到996007点心情。
以上每个项目只能最多消费一次,社会信用可以叠加,你现在有N元,请问你能得到的最大社会信用是多少?

题解

注意20不是社会信用,剩下只有7个,直接深度优先搜索每次取或者不取一个花费的,取个max即可。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
long long  n,res;
int st[10];
int w[10] = { 20,200,500,2000,20000,200000,2000000,20000000 };//处理一下数据
int v[10] = { 0 ,364364,500000,889464,8101919,11451419,18741515,19260817 };
void dfs(ll temp,ll vv)//当前剩余的钱以及获得的社会信用。
{    
	res = max(res, vv);
	for (int i = 0; i < 8; i++)
	{
		if (temp >= w[i] && !st[i])
		{
			st[i] = 1;
			dfs(temp - w[i], vv + v[i]);//选取一个
			st[i] = 0;//回溯
		}
	}
}
int main()
{
	
	cin >> n;
	dfs(n,0);
	cout << res << endl;
	
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值