首先感谢大家参加我们学校的新生赛!希望大家都玩的开心!

在此也对 题的失误致歉~( 题经后续检查,确定没有问题)

那么接下来是题解部分~

A 逐梦季

按要求随便输出即可。

#include <iostream>
using namespace std;

int main() {
    // 填入任意非空白内容(此处以"Programming!"为例)
    cout << "I Love ACM and Programming!" << endl;
    return 0;
}

B 美味的酱油

使用min函数/if结构判断均可。

#include <bits/stdc++.h>
using namespace std;
#define int long long

signed main()
{
    int n;
    cin>>n;
    cout<<min(n*5,100ll);
    return 0;
}

C 我的父亲是瓦匠

注意使用 会被卡精度。

#include <cstdio>
using namespace std;

int main() {
    double l, m; 
    scanf("%lf %lf", &l, &m);
    double area = l * m;
    printf("%.10f\n", area);
    return 0;
}

D 求和

注意使用 会被卡。

#include <bits/stdc++.h>
using namespace std;
#define ll long long
const ll N = 1e6 + 10;
ll a[N],b[N];
void solve() {
    int n;
    cin >> n;
    for(int i=1;i<=n;i++) cin >> a[i];
    for(int i=1;i<=n;i++) cin >> b[i];
    for(int i=1;i<=n;i++)
        cout << (a[i]+b[i]) << " ";
}

signed main() {
    ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
    ll _ = 1;
    // cin >> _;
    while (_--) solve();
    return 0;
}

E 第五

​ 小模拟,数组a用于计算编号为x的选手的积分,数组vis用来标记编号为x的选手是否淘汰,sum为剩余人数,初始值为6。

​ 当,当 后标记 ,同时 。最后跑一个 的循环将 即未淘汰的选手的积分加上 ,并不断取当前积分最大值求出冠军编号

#include <bits/stdc++.h>
using namespace std;
#define ll long long
void solve(){
    vector<ll> a(7, 0), vis(7, 0);
    ll sum = 6;
    ll q;
    cin >> q;
    while(q--) {
        ll op, x, y;
        cin >> op >> x >> y;
        if(vis[x]) continue;
        if(op == 1) a[x] += y;
        else {
            a[x] += y;
            vis[x] = 1;
            sum--;
        }
    }
    ll ans = 0, mx = 0;
    for (ll i = 1; i <= 6; i++) {
        if(vis[i] == 0) a[i] += 100 * sum;
        if(a[i] > mx) {
            mx = a[i];
            ans = i;
        }
    }
    cout << ans << '\n';
}
signed main(){
    ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
    ll _ = 1;
    // cin >> _;
    while (_--) solve();
    return 0;
}

F 两条线

​ 数学,给出两条直线 ,平行的条件为 等于 不等于 ,重合的条件为 等于 等于,其他情况为有唯一交点。该题即需要注意重合情况

#include <bits/stdc++.h>
using namespace std;
#define ll long long
void solve(){
    double k1, b1, k2, b2;
    cin >> k1 >> b1 >> k2 >> b2;
    if(k1 == k2) {
        if(b1 == b2) cout << "Wrong Answer\n";
        else cout << "Ping Xing";
        return ;
    }
    double x = 1.0 * (b2 - b1) / (k1 - k2);
    double y = k1 * x + b1;
    cout << fixed << setprecision(10) << x << " "  << y << '\n';
}
signed main(){
    ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
    // init();
    // Prime();
    cout << fixed << setprecision(6);
    ll _ = 1;
    // cin >> _;
    while (_--) solve();
    return 0;
}

G 摩天轮

该题涉及到时间,使用 scanf 能更好输入,根据题意能把22:00:00之前的摩天轮的转速 和之后的转速 求出来,并把输入的时间换算成以秒为单位的一个整数 ,以及22:00:00对应的整数 ,然后分类讨论算出最后角度即可。

#include <bits/stdc++.h>
using namespace std;
#define ll long long
void solve(){
	int hh, mm, dd, HH, MM, DD;
	scanf("%d:%d:%d %d:%d:%d", &hh, &mm, &dd, &HH, &MM, &DD);
	double v1 = 360.0 / (1.0 * 30 * 60);
	double v2 = 360.0 / (1.0 * 20 * 60);
	int t1 = hh * 3600 + mm * 60 + dd;
	int t2 = HH * 3600 + MM * 60 + DD;
	int t = 22 * 3600;
	double ans;
	if(t1 >= t) ans = (t2 - t1) * v2;
	else if(t2 <= t) ans = (t2 - t1) * v1;
	else ans = (t - t1) * v1 + (t2 - t) * v2;
	printf("%.1lf", ans);
}
signed main(){
//    ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
    ll _ = 1;
    // cin >> _;
    while (_--) solve();
    return 0;
}

H 鸡你太美

已知这 个鸡圈的容量都是 的幂次,且互不相同。因此,我们可以将它们看作二进制数的各个位。任意选择一些鸡圈,总容量就是这些鸡圈容量的和。由于每个鸡圈对应一个二进制位(选或不选),所以总容量可以表示 之间的任意整数(包括 )。

因此,问题转化为:判断 是否在 之间(包括两端)。由于题目中 ,所以实际上只需判断 是否小于等于

#include <bits/stdc++.h>
using namespace std;

int n, k;

int main() {
	cin >> n >> k;
	// 计算2^k - 1
	int max_capacity = (1 << k) - 1;
	if (n <= max_capacity)
		cout << "YES";
	else
		cout << "NO";
	return 0;
}

I 今天吃什么

​ 一共只有六个输入,将每次输入的食物进行统计次数求出票数最多的即可,因不保证票数完全相等,即可能最后有多个食物输出。

C:

#include<stdio.h>
#include<string.h>
int main(){
    char name[6][20];
    char food[20];
    int sum = 0;
    int cnt[6];
    for (int i = 1; i <= 6; i++) {
        scanf("%s", &food);
        bool flag = 0;
        for (int j = 0; j < sum; j++) {
            if(strcmp(name[j], food) == 0) {
                cnt[j]++;
                flag = 1;
                break;
            }
        }
        if(flag == 0) {
            strcpy(name[sum], food);
            cnt[sum] = 1;
            sum++;
        }
    }
    int mx = 0;
    for (int i = 0; i < sum; i++) {
        if(cnt[i] > mx) {
            mx = cnt[i];
        }
    }
    for (int i = 0; i < sum; i++) {
        if(cnt[i] == mx) {
            printf("%s\n", name[i]);
        }
    }
    return 0;
}

C++:

#include <bits/stdc++.h>
using namespace std;
#define ll long long
void solve(){
	map<string, ll> mp;
	ll mx = 0;
	for (ll i = 1; i <= 6; i++) {
		string s;
		cin >> s;
		mp[s]++;
		mx = max(mx, mp[s]);
	} 
	for (auto i : mp) {
		if(mx == i.second) cout << i.first << '\n';
	}
}
signed main(){
    ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
    ll _ = 1;
    // cin >> _;
    while (_--) solve();
    return 0;
}

J 是第一个”数学题“吗?

  • 考虑直接模拟 次多项式相乘,时间复杂度
  • 考虑展开多项式,设多项式为 ,因为求每项的系数,等价于 的值,带入原式:,时间复杂度
#include <bits/stdc++.h>

using namespace std;

constexpr int mod = 998244353;

int main() {
    ios::sync_with_stdio(false); cin.tie(nullptr);
    
    int n;
    cin >> n;
    
    int fac = 1;
    for(int i = 3; i <= n+1; i++) {
    	fac = 1ll*fac*i%mod;
    }
    
    cout << fac << '\n';

    return 0;
}

K 午枫爱操作

过手模不难发现,对于一段连续的 ,如果这段 右边至少有一个 ,那么可以通过一次操作使得这段 都变为 ,因为这段 一定是在高位的,所有这样的操作一定是最优的;由于操作后会出现新的 ,那么重复之前的过程,直到最后无法操作为止。

所以每次选取左端点为最左边的 ,右端点的距离左端点最近的 ,这样可以将这个区间除最后一位其他所有位都变成 ,同时提供了下一个区间的左端点,这样反复操作后,一定可以变成形如 的二进制数。

确定了上述方法,可以用模拟来实现,也可以记录最后一个 的位置直接输出。

时间复杂度

#include <bits/stdc++.h>
using namespace std;

void solve(){
    int n;cin>>n;
    string s;cin>>s;s=' '+s;
    
    bool flag=false;
    int pos=-1;
    for(int i=1;i<=n;i++){
        if(s[i]=='0') flag=true;
        if(flag && s[i]=='1') pos=i;
    }

    if(pos==-1){
        for(int i=1;i<=n;i++) cout<<s[i];
    }
    else{
        for(int i=1;i<pos;i++) cout<<1;
        for(int i=pos;i<=n;i++) cout<<0;
    }
}

int main(){
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    int T=1;//cin>>T;
    while(T--){
        solve();
    }
    return 0;
}

L 午枫的又一个01串

对于一个 串,如果我们进行的操作区间不在开头也不在结尾,即 满足 ,不难 从不同变为相同, 从不同变为相同。所以当我们对中间部分操作一次,度就会减

考虑完中间部分操作的影响,接下来考虑开头和结尾操作会有什么影响:

如果开头 ,则无法操作,同理,如果结尾 也无法操作。

如果开头 ,我们对区间 做一次操作后,由于 前面没有数字了,原本就没有度,所以左端点的改变不会的度产生影响, 从不同变为相同,因此此次操作会让度减少 。同理,对结尾 ,做一次操作也会让度减少

因此,先求出原串的度,优先对串的中间部分进行操作,在判断开头结尾的情况做出相应操作,计算度的减少量即可。

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'

void solve(){
    int n,m;cin>>n>>m;
    string s;cin>>s;s=' '+s;
    if(n==1){
        cout<<0<<endl;
        return;
    }

    int cnt=0;
    for(int i=1;i<n;i++){
        if(s[i]!=s[i+1]) cnt++;
    }

    if(cnt<2){
        cout<<cnt<<endl;
        return;
    }

    int ex=0;
    if(s[1]=='0') ex++;
    if(s.back()=='1') ex++;

    int need=0;
    need=(cnt-ex)/2;
    if(m>=need+ex) cout<<min(1ll,cnt)<<endl;
    else{
        if(ex==0) cout<<cnt-2*m<<endl;
        else if(ex==1){
            if(m<=need) cout<<cnt-2*m<<endl;
            else cout<<cnt-2*need-min(ex,m-need)<<endl;
        }
        else if(ex==2){
            if(m<=need) cout<<cnt-2*m<<endl;
            else cout<<cnt-2*need-min(ex,m-need)<<endl;
        }
    }
}

signed main(){
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    int T=1;//cin>>T;
    while(T--){
        solve();
    }
    return 0;
}

M ACM的数学题真的来了!

问题描述:无限平面上,用直线 圆环 正多边形最多可以将平面划分为几个区块?

直线将一个平面划分为两个部分:显然不会将任何两个直线的交点生成在已存在的交点上,因为可划分区域的直线数量不是最优。

当前的平面数量为 ,存在直线的情况下,无限平面为初始操作平面,但是不存在直线时,只存在封闭图形的操作,因此不断扩大的封闭区域为初始操作平面,因此不存在直线时,还应该加上操作不到的外部无限平面。

考虑直线 第 个直线与 个直线产生 个交点,局面新增 个直线,划分出 个新区域 设 表示 个直线划分的最多区域,则

考虑圆环 第 个圆环与 个圆环产生 个交点,局面新增 个弧线,划分出 个新区域 设 表示 个圆环划分的最多区域,则 , 个圆环与 个直线产生 个交点,局面新增 个直线,划分出 个新区域,则

考虑正 多边形() 与直线: <- 每条直线新增 2 个交点 与圆环: <- 每条边新增 2 个交点 与边数小于 的正多边形: <- 每条边新增 2 个交点 与自身:

据此只需要按照边数从小到大的方式遍历多边形,采用类似计数 (当然其实不用维护 数组,只需要实时知道有多少多边形比当前的边数少)的方式即可解决。时间复杂度

#include <bits/stdc++.h>

using namespace std;

#define int long long

constexpr int mod = 1e9+7;

signed main() {
    ios::sync_with_stdio(false); cin.tie(nullptr);
    
    int n;
    cin >> n;
        
    vector<int> a(n+1, 0);
    for(int i = 1; i <= n; i++) {
    	cin >> a[i];
    }
    
    bool valid = 1;
    if(a[2]>0)valid=0;
    
    int ans = 1;
    (ans += a[1]*(a[1]+1)/2 % mod) %= mod;
    (ans += (a[2] * a[1] * 2 % mod + a[2] * (a[2]-1) %mod) %mod) %= mod;

    for(int i = 3, sum = 0; i <= n; i++) {
    	(ans += (sum * a[i] % mod + a[i] * (a[i]-1) * i % mod) % mod) %= mod;
    	(ans += a[i] * ((a[1] * 2 % mod + a[2] * 2 * i % mod) % mod)) %= mod;
    	(sum += 2 * a[i] * i % mod) %= mod;
    	if(a[i]>0)valid=0;
    }
    
    if(a[1] == 0 && (!valid))
        ans++;
    
    cout << ans << '\n';
    
    return 0;
}