河南萌新联赛2024第(二)场:南阳理工学院
2024.7.24 13:00————15:00
过题数5/11
补题数6/11
- 国际旅行Ⅰ
- 国际旅行Ⅰ
- 小w和大W的决斗。
- A*BBBB
- “好”字符
- 水灵灵的小学弟
- lxy的通风报信
- 狼狼的备忘录
- 重生之zbk要拿回属于他的一切
- 这是签到
- Magic Cube
A - 国际旅行Ⅰ
题解:
n个国家,每个国家中a[i]个城市,国家之间一共修建了m条道路,q次询问每次输出从第一个国家能到达的城市数量第k少的国家有多少个城市。
这个问题的重点在于“保证各个国家之间可以相互到达”,所以就非常简单了,直接排序后输出第k少的国家即可。
代码:
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 1200;
int n,m,q;
int a[N];
signed main() {
cin >> n >> m >> q;
for (int i = 1; i <= n;i++) {
cin >> a[i];
}sort(a+1,a+1+n);
while(m--) {
int u,v;
cin >> u >> v;
}
while(q--) {
int k;
cin >> k;
cout << a[k] << endl;
}
return 0;
}
D - A*BBBB
题解:
求a*b的值,其中b的每一位都相同,a,b的长度小于1e6。
大概就是这么一个相乘的部分,a的长度小于b时中间会有一部分全部的相加,也可以画图得出。
代码:
#include<iostream>
#include<algorithm>
#include<vector>
#include<map>
#include<cmath>
using namespace std;
#define int long long
string a,b;
signed main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int t;
cin >> t;
while(t--) {
cin >> a >> b;
reverse(a.begin(),a.end());
int cur = 0,cur2 = 0;
string ans;
for (int i = 0; i < a.size()+b.size();i++) {
if(i < a.size())cur+=a[i]-'0';
//右半部分
if(i >= b.size())cur-=a[i-b.size()]-'0';
//后来就一直在减减减
cur2 += cur*(b[0]-'0');
//✖️总和
ans += cur2 % 10 +'0';
cur2/=10;
//上一位的进位
}
while(ans.size() > 1 && ans.back() == '0') {
//看看这一位到底有没有数字
//如果用if判断,注意0特殊情况,会有很多个0输出
ans.pop_back();
}
reverse(ans.begin(),ans.end());
cout << ans << endl;}
return 0;
}
F - 水灵灵的小学弟
题解:
取石子小游戏,balalabalala,然后输出胜利选手的名字大写首字母,可以发现俩个人的名字缩写是一样的,所以直接输入输出即可。
代码:
#include<bits/stdc++.h>
using namespace std;
#define int long long
int t;
signed main () {
cin >> t;
while(t--) {
int a,b;
cin >> a >> b;
cout << "DHY" << endl;
}
return 0;
}
H - 狼狼的备忘录
题解:
n本备忘录,每行给出成员名字,星座信息数量,星座信息,现在要求整理信息,如果星座信息x是y的后缀,只保留y,同一个成员的相同星座信息只保留一个,最后按照成员的名字字典序,星座信息字典序输出,格式要求成员名字 条目数信息 星座信息。
数据不大,可以直接暴力,在后缀方面稍微多写了一会,但其实也可以直接暴力for循环查找,set自动排序去重。
代码:
#include<bits/stdc++.h>
using namespace std;
#define int long long
int n;
map<string,pair<int,int>>mp;
vector<string>s[30];
signed main() {
cin >> n;
int t = 1;
for (int i = 1; i <= n; i++) {
string ls;
cin >> ls;
mp[ls].first++;
int p;
cin >> p;
if(mp[ls].first!=1) {
for (int i = 1; i <= p; i++) {
string la;
cin >> la;
s[mp[ls].second].push_back(la);
}
}
else {
mp[ls].second = t;
for (int i = 1; i <= p;i++) {
string la;
cin >> la;
s[t].push_back(la);
}
t++;
}
}cout << mp.size() << endl;
for (auto x :mp) {
cout << x.first << ' ';
set<string>ls;
sort(s[x.second.second].begin(),s[x.second.second].end());
for (auto y:s[x.second.second]) {
bool st = true;
for (auto z:s[x.second.second]) {
if(z.length() <= y.length())continue;
bool stt = true;
for (int i = 0; i < y.length(); i++) {
if(z[z.length()-1-i]!=y[y.length()-1-i]){
stt = false;
break;
}
}
if(stt){
st = false;
break;
}
}
if(st) {
ls.insert(y);
}
}
cout << ls.size() << ' ';
for (auto x : ls) {
cout << x << ' ';
}
cout << endl;
}
return 0;
}
I - 重生之zbk要拿回属于他的一切
题解:
给出一个字符串s,求其中子串chuan的数量。
直接暴力即可。
代码:
#include<bits/stdc++.h>
using namespace std;
#define int long long
int n;
string s;
signed main() {
cin >> n;
cin >> s;
int ans = 0;
for (int i = 0; i <= n-5; i++) {
if(s[i] == 'c' && s[i+1] == 'h' && s[i+2] == 'u' && s[i+3] == 'a' && s[i+4] == 'n')ans++;
}
cout << ans << endl;
return 0;
}//这是我一直以来的写法,但我忽然意识到一个问题,万一它特别长的话其实有点浪费时间,所以再给出一种写法
#include<bits/stdc++.h>
using namespace std;
#define int long long
int n;
string s;
signed main() {
cin >> n;
cin >> s;
int ams = 0;
for (int i = 0; i < n; i++) {
string g = s.substr(i,5);
//字符串的一些基本应用,本来想用find发现并不方便,而且大家都用的这个不知道为什么
if(g == "chuan")ams++;
}
cout << ams << endl;
return 0;
}
J - 这是签到
题解:
给出n行m列的行列式,求从(1,1)开始构成的最大的行列式。
数据较小,直接暴力即可,注意行列式的计算,全排列。
(我的代码太冗余了,给出示意代码)
代码:
#include<bits/stdc++.h>
#define int long long
#define ull unsigned long long
using namespace std;
typedef pair<int,int>PII;
typedef pair<int,PII>PPI;
const int N=2e5+7;
const int N1=1e7;
const int M=1e9+7;
const ull mask = std::chrono::steady_clock::now().time_since_epoch().count();
const int M1=19260817;
const int base=233;
const int base1=131;
int ans[N];
int A[15][15];
int p[10];
int get(int a[],int n)
{
int sum=0;
for(int i=1;i<=n;i++)
{
for(int j=i+1;j<=n;j++)
{
if(a[i]>a[j])sum++;
}
}
return sum;
}
void solve()
{
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
cin>>A[i][j];
}
p[i]=i;
}
int mi=1e18;
for(int k=1;k<=max(n,m);k++)
{
//每一维的值
int sum=0;
do{
int an=get(p,k);
//逆序对数量
int mul=pow(-1,an);
for(int j=1;j<=k;j++)
{
mul*=A[j][p[j]];
}
sum+=mul;
//加上所有的情况
}while(next_permutation(p+1,p+1+k));
mi=min(mi,sum);
}
cout<<mi<<"\n";
}
signed main()
{
std::ios::sync_with_stdio(false);
// cin.tie(0);cout.tie(0);
int _=1;
// cin>>_;
while(_--)
{
solve();
}
}