常州大学新生寒假训练会试 题解

题目链接

A - 添加逗号

注意是从后往前三个三个加逗号,最前面不允许有逗号

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

const int maxn = 1e5 + 10;
char s[maxn];
char ans[maxn];
int sz;

int main() {
  scanf("%s", s);
  int len = strlen(s);
  sz = 0;
  int t = 0;
  for(int i = len - 1; i >= 0; i --) {
    ans[sz ++] = s[i];
    ans[sz] = 0;
    t ++;
    if(t % 3 == 0 && i != 0) ans[sz ++] = ‘,‘, ans[sz] = 0;
  }
  len = strlen(ans);
  for(int i = len - 1; i >= 0; i --) {
    printf("%c", ans[i]);
  }
  printf("\n");
  return 0;
}

  

B - 对称

可以递归求解。

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

long long n, m;

long long work(long long r, long long c) {
  if(r % 2 == 0 || c % 2 == 0) return 0LL;
  return 4 * work(r / 2, c / 2) + 1LL;
}

int main() {
  scanf("%lld%lld", &n, &m);
  printf("%lld\n", work(n, m));
  return 0;
}

  

C - 竞赛技巧

排序。

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

const int maxn = 1e5 + 10;
struct X{
  int h, m, s;
  void out() {
    printf("%d %d %d\n", h, m, s);
  }
}s[maxn];
int n;

bool cmp(const X&a, const X&b) {
  if(a.h != b.h) return a.h < b.h;
  if(a.m != b.m) return a.m < b.m;
  return a.s < b.s;
}

int main() {
  scanf("%d", &n);
  for(int i = 1; i <= n; i ++) {
    scanf("%d%d%d", &s[i].h, &s[i].m, &s[i].s);
  }
  sort(s + 1, s + 1 + n, cmp);
  for(int i = 1; i <= n; i ++) {
    s[i].out();
  }
  return 0;
}

  

D - 训练技巧

设$dp[0][i]$表示以$i$为结尾的最大价值,$dp[1][i]$表示$j(j < i)$为结尾的最大价值。可见,该$dp$为$O(n^2)$效率的。

可以拿一个单调队列优化,明天更新。

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

const int maxn = 1e5 + 10;
int n, k;
long long a[maxn];
long long dp[2][maxn];
long long sum[maxn];

int q[5 * maxn];
int first, last;

bool check2(int a, int b) {
  if(dp[1][b] - dp[1][a] > sum[b] - sum[a]) return 1;
  return 0;
}

int main() {
  scanf("%d%d", &n, &k);
  for(int i = 1; i <= n; i ++) {
    scanf("%lld", &a[i]);
    sum[i] = sum[i - 1] + a[i];
  }

  /*
   dp[0][i] // 以i结尾
   dp[1][i] // 不以i结尾
   */

  first = 0, last = -1;

  for(int i = 1; i <= k; i ++) {
    dp[0][i] = sum[i];
    dp[1][i + 1] = max(dp[0][i], dp[1][i]);
    while(1) {
      if(last - first + 1 == 0) break;
      if(check2(q[last], i)) last --;
      else break;
    }
    last ++;
    q[last] = i;
  }

  for(int i = k + 1; i <= n; i ++) {
    while(1) {
      if(last < first) break;
      if(i - q[first] > k) first ++;
      else break;
    }
  /*
    printf("debug %d: ", i);
    for(int i = first; i <= last; i ++) {
      printf("%d ", q[i]);
    }
    printf("\n");
    */

    dp[0][i] = dp[1][q[first]] + sum[i] - sum[q[first]];
    dp[1][i + 1] = max(dp[0][i], dp[1][i]);

    while(1) {
      if(last - first + 1 == 0) break;
      if(check2(q[last], i)) last --;
      else break;
    }

    last ++;
    q[last] = i;
    /*
    printf("debug %d: ", i);
    for(int i = first; i <= last; i ++) {
      printf("%d ", q[i]);
    }
    printf("\n");
     */
  }

  for(int i = 1; i <= n; i ++) {
   // printf("%d %lld %lld\n", i, dp[0][i], dp[1][i]);
  }

  long long ans = 0;
  for(int i = 1; i <= n; i ++) {
    ans = max(ans, dp[0][i]);
    ans = max(ans, dp[1][i]);
  }
  printf("%lld\n", ans);
  return 0;
}

  

E - 这是一个数学题

化简之后可以发现$A_i = A_0*\frac{n-i}{n} + A_n*\frac{i}{n}$,这样就很容易求解了。

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.*;

public class Main {
    static Scanner cin = new Scanner(System.in);

    public static void main(String[] args) {
        int n = cin.nextInt();
        long a0 = cin.nextLong();
        long an = cin.nextLong();
        int Q = cin.nextInt();
        while(Q -- > 0) {
            long L = cin.nextLong();
            long R = cin.nextLong();
            long len = R - L + 1;

            BigInteger ans = BigInteger.ZERO;
            BigInteger A = BigInteger.ZERO;;
            BigInteger B = BigInteger.ZERO;;

            long x = len * n;
            long y = (L + R) * len / 2;

            A = BigInteger.valueOf(x).subtract(BigInteger.valueOf(y));
            A = A.multiply(BigInteger.valueOf(a0));
            A = A.divide(BigInteger.valueOf(n));

            B = BigInteger.valueOf(an).multiply(BigInteger.valueOf(y)).divide(BigInteger.valueOf(n));

            ans = A.add(B);

            System.out.println(ans);
        }
    }
}

  

F - 大佬的生日大礼包

如果$x$个人能满足,那么$[0,x]$个人都能满足,依据这个性质,我们可以对答案进行二分。

接下来就是验证$x$个人能否满足:

首先观察到,无论是哪一种大礼包,都会用掉一个U盘和一个鼠标,除此之外,每种礼包再外加一个物品。

因此U盘或者鼠标数量不足$x$个,则无解。

将U盘和鼠标数量都减去$x$个后,问题就变成了:三种物品分别有$p_0$,$p_1$,$p_2$个,问是否存在排列方案使得相邻两个物品种类不同。

只要验证$\sum_{i=0}^2min(p_i, \frac{x+1}{2})$和$x$的大小关系即可。

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

int T, a, b ,c;

int check(int x) {
  int p[3];
   p[0] = a - x;
   p[1] = b - x;
   p[2] = c;
  if(p[0] < 0 || p[1] < 0) return 0;
  for(int i = 0; i < 3; i ++) {
    p[i] = min(p[i], (x + 1) / 2);
  }
  if(p[0] + p[1] + p[2] >= x) return 1;
  return 0;
}

int main() {
  scanf("%d", &T);
  while(T --) {
    scanf("%d%d%d", &a, &b, &c);
    int L = 0, R = a + b + c, ans = 0;
    while(L <= R) {
      int mid = (L + R) / 2;
      if(check(mid)) ans = mid, L = mid + 1;
      else R = mid - 1;
    }
    printf("%d\n", ans);
  }
  return 0;
}

  

G - 零下e度

公式1:$\frac{1}{e}= \sum_{i = 0}^{\infty} (-1)^i\frac{1}{i!}$

公式2:$e= \sum_{i = 0}^{\infty} \frac{1}{i!}$

知道上面这个公式就会做了。这题卡常数,$mod$如果不是const定义的话容易超时。

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

const int mod = 998244353LL;
long long ans;
int n;

int main() {
  scanf("%d", &n);
  long long u = 1;
  int p = (n % 2) ? -1 : 1;
  for(int i = n; i >= 1; i --) {
    ans = (ans + p * u + mod) % mod;
    u = (u * i) % mod;
    p = p * -1;
  }
  ans = (ans + u) % mod;
  printf("%lld\n", ans);
  return 0;
}

  

H - 酸碱滴定

模拟题。还没写。

I - 合成反应

暴力,每次判断那些还不能执行的方程式,直到不能增加元素为止。

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

const int maxn = 1e5 + 10;
int f[maxn];
int a[maxn], b[maxn], c[maxn];
int q, n, k, m;
set<int> st;

int main() {
  scanf("%d%d%d%d", &k, &n, &m, &q);
  for(int i = 1; i <= n; i ++) {
    scanf("%d%d%d", &a[i], &b[i], &c[i]);
    st.insert(i);
  }
  for(int i = 1; i <= m; i ++) {
    int x;
    scanf("%d", &x);
    f[x] = 1;
  }
  vector<int> vec;
  while(!st.empty()) {
    set<int>::iterator it;
    vec.clear();
    for(it = st.begin(); it != st.end(); it ++) {
      int id = *it;
      if((f[a[id]] && f[b[id]]) || f[c[id]]) {
        f[a[id]] = 1;
        f[b[id]] = 1;
        f[c[id]] = 1;
        vec.push_back(id);
      }
    }
    if(vec.size() == 0) break;

    for(int i = 0; i < vec.size(); i ++) {
      st.erase(vec[i]);
    }
  }

  while(q --) {
    int x;
    scanf("%d", &x);
    printf("%s\n", f[x] ? "Yes" : "No");
  }
  return 0;
}

  

J - 同分异构体

手算 or OEIS

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

int ans[] = {1, 1, 1, 1, 2, 3, 5, 9, 18, 35, 75, 159};

int main() {
  int n;
  scanf("%d", &n);
  printf("%d\n", ans[n]);
  return 0;
}

  

原文地址:https://www.cnblogs.com/zufezzt/p/8428551.html

时间: 2024-10-29 10:47:49

常州大学新生寒假训练会试 题解的相关文章

常州大学新生寒假训练会试 I 合成反应

1 题目描述 2 有机合成是指从较简单的化合物或单质经化学反应合成有机物的过程. 3 有时也包括从复杂原料降解为较简单化合物的过程. 4 由于有机化合物的各种特点,尤其是碳与碳之间以共价键相连,有机合成比较困难,常常要用加热.光照.加催化剂.加有机溶剂甚至加压等反应条件. 5 但是前人为有机合成提供了许多宝贵的经验. 6 现在已知有K总物质和N个前人已经总结出的合成反应方程式 7 小星想知道在现有M种物质的情况下 能否合成某些物质. 8 输入描述: 9 第一行输入四个整数 K,N,M,Q(K,N

FJUT2017寒假训练二题解

A题 题意:让你找出唯一的一个四位数,满足对话时的要求. 思路:因为是4位数,可以直接从1000-9999遍历一遍,判断是否有唯一的数能满足所有条件,如果不是唯一的或者没有满足条件的数就输出Not sure.特别丑的代码附上... 1 #include<stdio.h> 2 int a[10000],b[10000],c[10000]; 3 int main() 4 { 5 int n; 6 while(~scanf("%d",&n)) 7 { 8 if(n==0)

周一训练赛题解

这次完全是水题大集合啊,希望大家A的开心: 前两个题是我找的,后两个是陶叔找的,另外因为我的偷懒,下面所有的代码都是陶叔亲自写的,十分感谢陶叔: 陶叔暑假为了大家的集训,牺牲了很多自己宝贵的时间,大家接下来要好好训练啊!!!! 废话少说,进入正题: Problem A      SPOJ QUEST5 签到题: 将所有的边按照右端点排个序,然后每次选择没有钉住的点,然后把这之后的所有与它相交的边全去掉: 代码: #include <cstdio> #include <cstring>

模板方法模式 - 大学新生报到案例

每年9月份,大学生开学季,社会主义的接班人们将进入向往的大学学习..... 大学报到有一个流程,咱们目前就简单分为两步,1.找学校,2.交学费 任何专业的学生都要执行找学校,但是每个专业的学生的学费价格有所不同 那我们就来实现大学报到. 一.报到第一步:找学校. 报到第一步找学校,这点就不用解释了.. public abstract class Register { /** * 去学校 */ public final void goToSchool() { System.out.println(

2020.2.8铁一寒假收官赛题解

2020.2.8铁一寒假收官赛题解 题目均为原题或改编,已得到题主许可 出题人:Memoryヾノ战心 BigYellowDog选手写了份题解,得到出题人许可 T1 这道题是一道很经典的简单dp模型(不会dp的可以先去自学简单入个门 有O(n方)或者O(nlogn)的做法,数据范围n最大不超200,显然O(n方)算法足矣 题目要求最少抽出几本书,可以转化为求最长"舒服样子"序列的元素个数w.答案即为:n-w 具体思路就是定义数组dp1[], dp2[] dp1[i]表示从左到右看,以第i

2018.12.2 中国石油大学第一次新生训练赛题解

整理人: 周翔 A题:李继朋 B题:李继朋 H题:魏斯博 原文地址:https://www.cnblogs.com/QLU-ACM/p/10057831.html

训练赛题解

突然想到好久以前做完这份题目没写题解.蛮来写写吧.很多细节已经忘记了.. 第一题 很简单的字符串比对是否b包含a.不包含就报NO,包含就YES..坑爹的第一次!!.把strlen放在了for循环里面..就超时了..超时了.. 注意:for里面的条件每次也会重新计算. A - All in All Time Limit:1000MS     Memory Limit:30000KB     64bit IO Format:%I64d & %I64u Submit Status Practice P

2015多校训练5题解与代码

首先呢,要废话一段..这场是见过的所有多校中最最亲民的.因为英文题面都很短.但是是最考验智商的一次(除去那个化学第一电离能)... 赛后补题在题解和各大巨巨的帮助下能够补到7题也是醉了.说明题就是考模型建立,没有考到多深的知识点. 戳我见官方题解 1002:HDOJ 5344 第一眼看上去就是亦或啊,又是数学啊,又是不能暴力的.the xor of all (Ai+Aj)(1≤i,j≤n)这是关键句.根据题意把需要的写出来,发现所有i!=j的,都可以利用a^a=0消除,所有只剩下i==j的.最后

NUC-ACM/ICPC 寒假训练 简单DP A - G题

第一题:数塔 HDU - 2084 做法: 从第 i , j 个 节点往下走的最优解可以由从第 i+1,j 个节点往下走的最优解和第i+1,j+1个节点往下走的最优解得出,二者取其优即可. 代码: 记忆化搜素 1 #include<iostream> 2 using namespace std; 3 #include<cstdio> 4 using namespace std; 5 int n; 6 int f[100][100]; 7 int v[100][100]; 8 int