天元公学-2023届信奥期中考题解

天元公学-2023届信奥期中考题解

\(\text{A Maths}\)

  • 出题人评价:语文题

  • 形式化题意:输入 \(a,b,c\),输出 \(\text{lcm}(a,\text{lcm}(b,c))\)

\(\text{lcm}(a,b)\) 代表 \(a\)\(b\) 两数的最小公倍数。

  • \(40\) 分代码,一个一个 \(x\) 枚举。
// code by st
#include<bits/stdc++.h>
#define int long long
using namespace std;
signed main(){
	int a,b,c;
	cin>>a>>b>>c;
	int mi=max(a,b);
	mi=max(mi,c);
	for(int i=mi;;i++){
		if(i%a==0&&i%b==0&&i%c==0) {
			cout<<i;
			return 0;
		}
	}
	return 0;
}
  • \(100\) 分代码思路,首先需要用 \(O(\log n)\) 的时间处理出 \(\gcd(a,b)\),然后因为 \(\text{lcm}(a,b)=a\times b\div \gcd(a,b)\),就可以 \(O(\log n)\) 的时间求出 \(\text{lcm}(a,b)\)
// code by sjh
#include <bits/stdc++.h>
using namespace std;
#define ll long long
ll lcm(ll x,ll y){
	return x*y/__gcd(x,y);
}
int main(){
	ll a,b,c;
	scanf("%lld %lld %lld",&a,&b,&c);
	printf("%lld\n",lcm(a,lcm(b,c)));
	return 0;
}

\(\text{B Jewel}\)

  • 出题人评价:诈骗题

  • 首先,可以进行 \(10^{567}\) 操作,所以可以交换出任意的二维矩阵。

  • 我们要求 $ \max {\textstyle \sum_{i=1}^{n}} {\textstyle \sum_{j=1}^{m}} (A'_{i,j}\times ((i-1)\times n+j))$,所以我们可以让这 \(n\times m\) 个数从小到大排序计算即可。

//code by sjh
#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int MAXN=30*30;
ll ans=0,a[MAXN];
int main(){
	int n,m;
	scanf("%d %d",&n,&m);
	for(int i=1;i<=n*m;++i){
		scanf("%lld",&a[i]);
	}
	sort(a+1,a+n*m+1);
	for(int i=1;i<=n*m;++i){
		ans=ans+a[i]*i;
	}
	printf("%lld\n",ans);
	return 0;
}

\(\text{C X-operator}\)

  • 出题人评价:简单模拟题

  • 如果当前这个数 \(a_i\)\(1\),那么 \(ans=ans\times a_i\),也就是 \(a_i\) 不变。

  • 如果当前 \(ans\)\(1\),那么 \(ans=ans\times a_i\),也就是 \(ans=a_i\)

  • 否则 \(ans=ans+a_i\)

// code by sjh
#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int MAXN=1e6+5;
ll a[MAXN];
int main(){
	int n;
	scanf("%d",&n);
	for(int i=1;i<=n;++i){
		scanf("%lld",&a[i]);
	}
	ll ans=min(a[1]+a[2],a[1]*a[2]);
	for(int i=3;i<=n;++i){
		if (a[i]==1) ans=ans;
		else if (ans==1) ans=a[i];
		else ans=ans+a[i];
	}
	printf("%lld\n",ans);
	return 0;
}

\(\text{D Translating}\)

  • 出题人评价 \(\text{STL}\)

  • 没有任何含金量,用 \(\text{map}\) 或者直接暴力枚举就能过。

//code by st
#include<bits/stdc++.h>
using namespace std;
int s[128];
int main(){
	int n,m;
	cin>>n;
	for(int i=1;i<=n;i++){
		char a,c;
		cin>>a>>c;
		if ((a>='a'&&a<='z')||(a>='A'&&a<='Z')){
			s[int(a)]=int(c);
		}
	}
	string sb;
	cin>>sb;
	for(int i=0;i<sb.size();++i){
		if ((sb[i]>='a'&&sb[i]<='z')||(sb[i]>='A'&&sb[i]<='Z')){
			if(s[int(sb[i])]==0){
				printf("%c",sb[i]);
			}
			else{
				printf("%c",s[sb[i]]);
			}
		}
		else{
			cout<<"sb";
		}
	}
	return 0;
}
//code by yyyx
#include<bits/stdc++.h>
using namespace std;
int n;
char ch1, ch2;
map<char, char> mp;
string a;
int main()
{
	scanf("%d", &n);
	for (int i = 1; i <= n; i++)
		cin >> ch1 >> ch2, mp[ch1] = ch2;
	cin >> a;
	for (int i = 0; i < a.size(); i++)
		putchar(mp.count(a[i]) ? mp[a[i]] : a[i]);
	
	return 0;
}

\(\text{E Zealous}\)

  • 出题人评价 小小思维题

  • 如果第 \(i\) 个数硬币与第 \(i+1\) 个硬币不相同的面朝上,则答案 \(+1\)

  • 如果最会一个硬币 \(0\) 面朝上,则答案 \(+1\)

//code by sjh
#include <bits/stdc++.h>
using namespace std;
#define ll long long
int sum;
int main(){
	string s;
	cin>>s;
	for(int i=0;i<s.size()-1;++i){
		if(s[i]!=s[i+1]) sum++;
	}
	if(s[s.size()-1]=='0') ++sum;
	printf("%d\n",sum);
}

\(\text{F Lament}\)

  • \(\text{DP}\) 题,超纲了,这里只放代码。
//code by st
#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,a[100005],f[100005][5];
inline int read(){
    int f = 0, x = 1; char ch = getchar();
    while(ch < '0' || ch > '9'){
        if(ch == '-') x = -1;
        ch = getchar();
    }
    while(ch >= '0' && ch <= '9'){
        f = f * 10 + ch - '0';
        ch = getchar();
    }
    return f * x;
}
signed main(){
	n=read();
	for(int i=1;i<=n;i++){
		a[i]=read();
	}
	for(int i=1;i<=n;i++){
		f[i][0]=f[i-1][1];
		f[i][1]=max(f[i-1][0],f[i-1][1])+a[i];
	}
	cout<<max(f[n][0],f[n][1]);
	return 0;
}
//code by yyyx
#include<bits/stdc++.h>
using namespace std;
int n;
int main()
{
	scanf("%d", &n);
	vector<int> a(n);
	for (auto &x : a)
		scanf("%d", &x);
	vector<array<int, 2> > f(n, {-0x7fffffff, -0x7fffffff});
	f[0][0] = f[0][1] = a[0];
	f[1][1] = a[1];
	for (int i = 1; i < n; i++)
	{
		f[i][0] = max(f[i - 1][0], f[i - 1][1]) + a[i];
		if (i > 1)
			f[i][1] = max(f[i - 2][0], f[i - 2][1]) + a[i];
	}
	printf("%d", max(max(f[n - 2][0], f[n - 2][1]), max(f[n - 1][0], f[n - 1][1])));
	
	return 0;
}

如果你有任何疑问,欢迎在评论区留言,谢谢!

posted @ 2024-04-19 13:31  Jasonshan10  阅读(101)  评论(0)    收藏  举报