第八届“图灵杯”NEUQ-ACM程序设计竞赛个人赛(同步赛)

题目总结

A题 切蛋糕

题目信息

解题思路

如果我们将 1/k展开到二进制的形式,那么就可以计算出 需要 多少块1/(2^i) 蛋糕,因此就可以创建出分割的方案,最后进行打包。
本题还有一个有趣的地方是,知道需要多少块的蛋糕后,还需要计算出需要切割多少次,
假如说需要 1个四等分的, 1个八等分的,3个十六等分的,4个三十二等分的
那么 十六等分的需要切割次数 ⌈\lceil⌈42\frac{4}{2}24​⌉\rceil⌉=2,可以得到四个三十二等分
八等分需要的切割次数 ⌈\lceil⌈十六等分切割次数+十六等分原需要数额2\frac{十六等分切割次数+十六等分原需要数额}{2}2十六等分切割次数+十六等分原需要数额​⌉\rceil⌉
也就是说,计算切割次数,需要受到前面切割次数信息的影响。

二进制小数点可以直接使用double进行计算,精度是足够的

AC代码

#include <bits/stdc++.h>
using namespace std;typedef long long LL;
const double esp = 1e-10;
const int N = 20;
LL a[N];
LL k;
bool b[N], flag;
int opt[N];
int cut_opt[N];bool Check(int n)
{static LL l = a[10] - k, r = a[10] + k;double sum = 0;for (int i = 0; i < n; i ++ ){if (!b[i])  continue;if (i <= 10)sum += (a[10 - i]) * k;elsesum += k * 1.0 / a[i - 10];}if (n <= 10)    //  (a[10 - i]) * k{static int i;   i = n;if (sum + (a[10 - i]) * k >= l && sum + (a[10 - i]) * k <= r){flag = true;return true;}else if (sum + (a[10 - i]) * k < l)return true;return false;}else    // 1.0 / a[i - 10];{static int i;   i = n;if (sum + k * 1.0 / a[i - 10] >= l && sum + k * 1.0 / a[i - 10] <= r){flag = true;return true;}else if (sum + k * 1.0 / a[i - 10] < l)return true;return false;}
}int main()
{a[0] = 1;for (int i = 1; i < N; i ++ )a[i] = (a[i - 1] << 1);memset(b, false, sizeof b);cin >> k;if (k == 1)     // 注意{printf("1\n");printf("2 1 0\n");return 0;}flag = false;double tmp = 1.0 / k;for (int i = 1; i <= 15; i ++ ){if (abs(tmp - 1.0 / a[i]) <= esp){b[i] = true;break;}else if (tmp >= 1.0 / a[i]){tmp -= 1.0 / a[i];b[i] = true;}else{b[i] = false;}}/*for (int i = 0; i < 15; i ++ ){printf("i=%d, b[%d]=%d\n", i, i, b[i]);}
*/for (int i = 15; i >= 1; i -- ){opt[i] = b[i] * k;}int outcnt = k;memset(cut_opt, 0, sizeof cut_opt);for (int i = 14; i >= 1; i -- ){cut_opt[i - 1] = (opt[i] + 1) / 2;opt[i - 1] += ((opt[i] + 1) / 2);outcnt += cut_opt[i - 1];}cout << outcnt << endl;// 需要切割的for (int i = 0; i < 15; i ++ ){if (cut_opt[i] != 0){for (int j = 1; j <= cut_opt[i]; j ++ )printf("1 %d\n", i);}}int cnt = 0;vector<int> pick;// b[i] 打包的for (int i = 0; i < 15; i ++)if (b[i]){cnt += b[i];pick.push_back(i);}for (int i = 1; i <= k; i ++ ){printf("2 %d", cnt);for (int j = 0; j < pick.size(); j ++ )printf(" %d", pick[j]);putchar('\n');}return 0;
}

小宝的幸运数组

题目信息

解题思路

需要注意子序列(如最长上升子序列LIS)和子串的区别
这里子数组的定义和子串类似
这里关键是对 原数组的前缀和 对k进行求余,得到的余数k,记录下来他的位置,然后对余数进行分析
余数 = 0,可以直接将下边作为一种解,进行更新答案
余数 = 1, res = min(res, max - min); 也就是说最长的,min + 1 ~ max这一段子序列是可行的,而且是余数等于1情况下最长的。

余数 = k-1
经过分析,发现子需要记录下来 余数中最先遇到的 min下标,与最后遇到的 max下标即可。

AC代码

#include <bits/stdc++.h>
using namespace std;typedef long long LL;
const int N = 100010;
const int INF = 0x3f3f3f3f;
int a[N], b[N];
int n, k;
LL q[N], sum[N];int main()
{int T;  cin >> T;while (T -- ){cin >> n >> k;sum[0] = 0;memset(a, -1, sizeof a);memset(b, -1, sizeof b);int res = -1;for (int i = 1; i <= n; i ++ ){scanf("%lld", &q[i]);sum[i] = (sum[i - 1] + q[i]) % k;if (a[sum[i]] == -1){a[sum[i]] = i;}b[sum[i]] = i;if (sum[i] == 0){res = max(res, i);}else{res = max(res, b[sum[i]] - a[sum[i]]);}}/// cout << "###########\n";if (res == 0)   puts("-1");else    cout << res << endl;}return 0;
}

C题上进的凡凡

题目信息

解题思路

关键的思路就是使用dp的思想
以 a[i] 为开始的上进数组个数 f[i]
a[i]<=a[i+1]
f[i] = 1 + f[i + 1]
否则
f[i] =1
最后累加求和即可

AC代码

#include <bits/stdc++.h>
using namespace std;typedef long long LL;const int N = 100010, INF = 0x3f3f3f3f;
int a[N], f[N];
int n;int main()
{cin >> n;for (int i = 1; i <= n; i ++ )scanf("%d", &a[i]);LL res = 0;a[n + 1] = -INF;for (int i = n; i >= 1; i -- ){f[i] = 1;if (a[i] <= a[i + 1])f[i] += f[i + 1];res += f[i];}cout << res << endl;return 0;
}

D题Seek the Joker I

原题信息

解题思路

本题是博弈论方向的题目,对于此类问题,我们需要从 必定失败的局面出发,推导出可以让对手达到必定失败的局面-》必胜
以及无法让对手达到必定失败的局面->必败,最后找到规律,有时间可以证明,写出结果即可

AC代码

#include <bits/stdc++.h>
using namespace std;bool Check(int n, int k)
{if (n % (k + 1) == 0)   return false;return true;
}
int main()
{int t;  cin >> t;while (t -- ){static int n, k;scanf("%d%d", &n, &k);if (Check(n - 1, k)){/// cout << "win" << endl;puts("yo xi no forever!");}else{/// cout << "lose" << endl;puts("ma la se mi no.1!");}}return 0;
}

E Seek the Joker II

原题信息

解题思路

方法与上题目相同,但是推导比较易错,** 最终的规律可以使用dp的形式表达出来 **

AC代码

#include <bits/stdc++.h>
using namespace std;typedef long long LL;
const int N = 3000010;
bool st[N + 1000000];
LL a[N + 1000000];bool Check(int x, int y)
{if (a[x] == -1) return true;    // winelse if (a[x] == y) return false;   // losereturn true;    // win
}int main()
{memset(a, -1, sizeof a);memset(st, false, sizeof st);a[0] = 0;int cur = 1;for (int i = 1; i < N; i ++ ){if (st[i]){/// if (i <= 20)    printf("I=%d, st\n\ta[i]=", i);a[i] = -1;}else{/// if (i <= 20)    printf("I=%d, No_St\n\ta[i]=", i);a[i] = i + cur;if (i + cur <= N)st[i + cur] = true; // 注意这个cur ++;}/// if (i <= 20)    cout << a[i] << endl;}
/*cout << a[0] << endl;for (int i = 0; i <= 9; i ++ ){printf("i=%d, a[i]=%lld\n", i, a[i]);}
*/int t;  cin >> t;int x, n, mina, maxb;while (t -- ){scanf("%d%d", &n, &x);mina = x - 1, maxb = n - x;if (mina > maxb)  swap(mina, maxb);/// printf("a=%d, b=%d\n", mina, maxb);if (Check(mina, maxb))/// cout << "\t##win\n",cout << "yo xi no forever!" << endl;else/// cout << "\t##lose\n",cout << "ma la se mi no.1!" << endl;}return 0;
}

成绩查询ing

原题信息

解题思路

思路很清晰的模拟题,就是排序,查找,不会stl顶多就是再加一个二分
但是 时间很卡 应该使用快读 来解决时间的问题,考试的时候没有板子,就T了

AC代码

#include <bits/stdc++.h>
using namespace std;
const int BASE1 = 10, BASE2 = 10000;
map<string, int> t1;
set<string> t2[101];int n, m, opt;inline int IntRead()//内联函数稍微快一点点
{char ch = getchar();int s = 0, w = 1;while(ch < '0' || ch > '9'){if(ch == '-') w = -1;ch = getchar();}while(ch >= '0' && ch <= '9'){s = s * 10 + ch - '0',ch = getchar();}return s * w;
}inline string StringRead()
{string str;char s = getchar();//处理多余回车或空格while (s == ' ' || s == '\n' || s == '\r'){s = getchar();}//不断读入直到遇到回车或空格while (s != ' ' && s != '\n' && s != '\r'){str += s;s = getchar();}return str;
}inline void StringWrite(std::string str)
{int i = 0;while (str[i] != '\0'){putchar(str[i]), i++;}
}inline void IntWrite(int s)
{int k = 0, len = 0;if (s == 0)putchar('0');while (s){k = k * 10 + s % 10;s /= 10, len++;}for (int i = 0;i < len;i++){putchar(k % 10 + '0');k /= 10;}
}int main()
{cin >> n;string _name;   int _id, _sex, _grade;for (int i = 1; i <= n; i ++ ){_name = StringRead();_grade = IntRead(), _sex = IntRead(), _id = IntRead();t2[_grade].insert(_name);t1[_name] = _sex + BASE1 * _grade + BASE2 * _id;}cin >> m;while (m -- ){opt = IntRead();if (opt == 1){_name = StringRead();static int num;num = t1[_name];printf("%d %d %d\n", num % BASE2 / BASE1, num / BASE2, num % BASE1);}else{_grade = IntRead();static set<string>::iterator it;for (it = t2[_grade].begin(); it != t2[_grade].end(); it ++ ){StringWrite(*it);putchar('\n');}}}return 0;
}
/*
5
N 28 2 7475
UN 83 2 27550
EXF 28 2 17298
OVYNH 51 2 14827
XNV 53 1 7591
2
1
XNV
2
28
*/

G 贪吃的派蒙

原题信息

解题思路

关键就是改变其他人领取的数量,来使得派蒙的前一个人刚刚好领完,这是一个 数学 区间 + 不等式的问题

最后注意上下取整就好

H数羊

原题信息

解题思路

直接打表找规律,我是证明半天没出来,最后快没时间了,才打的表,血亏

AC代码

#include <bits/stdc++.h>
using namespace std;const int MOD = 998244353;
typedef long long LL;int fun(int x, int y)
{if (x == 1 && y == 0)   return 2;else if (x == 0 && y >= 0)  return 1;else if (x >= 2 && y == 0)  return x + 2;else    return fun(fun(x - 1, y), y - 1);
}int qmi(LL a, int k, int MOD)
{LL res = 1;while (k){if (k & 1){res = (res * a) % MOD;}a = a * a % MOD;k >>= 1;}return res;
}int cal(int x, int y)
{if(x == 1)  return 2;if (y == 0){return (x + 2) % MOD;}else if (y == 1){return (x * 2) % MOD;}else{return qmi(2, x, MOD);}
}int main()
{/*for (int i = 1; i <= 18; i ++ ){printf("i=%d, ", i);for (int j = 0; j <= 2; j ++ ){printf("%d, ", fun(i, j));}cout << endl;}*/int t;  cin >> t;while (t -- ){static int x, y;scanf("%d%d", &x, &y);printf("%d\n", cal(x, y));}}

I 买花

原题信息

解题思路

直接就是 2i2^i2i 的前缀和,但是要注意 不可以是一天的

AC代码

#include <bits/stdc++.h>
using namespace std;int a[200];bool Check(int x)
{for (int i = 2; i <= 15; i ++ ){if (x % a[i] == 0)return true;}return false;
}int main()
{a[1] = 1;for (int i = 2; i <= 15; i ++ ){a[i] = (a[i - 1] << 1);}for (int i = 1; i <= 15; i ++ )a[i] = a[i - 1] + a[i];int t;  cin >> t;while (t -- ){static int n;scanf("%d", &n);if (Check(n)){puts("YE5");}else{puts("N0");}}return 0;
}

J 这是一题简单的模拟

原题信息

解题思路

直接就是模拟就行了,关键是题目描述的不太清楚,多读几遍 就好了
对于一个可行的道路,必须要经过所有的城市,是N个,不是n个

AC代码

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
using namespace std;const int N = 310, INF = 0x3f3f3f3f;
int n, m;
int e[N][N];
bool st[N];
int k;
int path[N * 1000];
int res = INF;int main()
{cin >> n >> m;memset(e, 0x3f, sizeof e);for (int i = 1; i <= m; i ++ ){static int x, y, w;scanf("%d%d%d", &x, &y, &w);e[x][y] = e[y][x] = w;}cin >> k;res = INF;int tmpres;while (k -- ){tmpres = 0;static int n2;  scanf("%d", &n2);for (int i = 1; i <= n2; i ++ )scanf("%d", &path[i]);if (n2 != n)continue;n2 ++;  path[n2] = 0;path[0] = 0;memset(st, false, sizeof st);for (int i = 1, pre, cur; i <= n2; i ++ ){pre = path[i - 1], cur = path[i];if (st[cur] == true){tmpres = INF;break;}st[cur] = true;if (e[pre][cur] == INF){tmpres = INF;break;}tmpres += e[pre][cur];}res = min(res, tmpres);}if (res == INF) res = -1;cout << res << endl;return 0;
}

K黑洞密码

原题信息

解题思路

就是一个简单的字符串问题,和模拟相关,注意 字母谁在谁的后面,特判就好

AC代码

#include <bits/stdc++.h>
using namespace std;const int N = 100;
int num[N];
char str[N];
char s[N];
int nidx, cidx;char Change(char ch, int num)
{if (ch >= 'A' && ch <= 'Z'){if (ch + num <= 'Z')    return ch + num;else    return ch + num - 'Z' - 1 + 'b';}else{if (ch + num <= 'z')    return ch + num;else    return ch + num - 'z' - 1 + 'B';}
}int main()
{nidx = cidx = 0;cin >> str;for (int i = 0; i < 32; i ++ ){if (str[i] >= '0' && str[i] <= '9'){num[nidx ++] = str[i] - '0';}else{s[cidx ++] = str[i];}}for (int i = 0; i < 16; i ++ ){s[i] = Change(s[i], num[i]);}for (int i = 0; i < 4; i ++ ){for (int j = 3 + i * 4; j >= i * 4; j -- ){cout << s[j];}}cout << endl;return 0;
}

L建立火车站

原题信息

解题思路

求最大值最小,典型的 二分

AC代码

#include <bits/stdc++.h>
using namespace std;typedef long long LL;
const int N = 100010;LL a[N];
LL n, k;bool Check(LL l, LL k)
{if (l == 0){for (int i = 2; i <= n; i ++){if (a[i] != a[i - 1])   return false;}return true;}LL dist;for (int i = 2; i <= n; i ++ ){dist = a[i] - a[i - 1];k = k - (dist - 1) / l;if (k < 0)  return false;}return true;
}int main()
{cin >> n >> k;for (int i = 1; i <= n; i ++ )scanf("%lld", &a[i]);sort(a + 1, a + n + 1);LL l, r, mid;l = 0, r = 1e12+10;while (l < r){mid = l + r >> 1;if (Check(mid, k)){r = mid;}else{l = mid + 1;}}cout << l << endl;return 0;
}

心得体会

题目信息要读懂,读清楚,不要漏掉信息,结合样例

空间开的足够,LL信息需要注意

输出的字符串YES,NO不要自己打,直接复制粘贴

快读卡时间,记得打板子

double精度很高的,不必转换为整数求二进制信息

一些数学题目,先打表找规律,别直接推导

第八届“图灵杯”NEUQ-ACM程序设计竞赛个人赛(同步赛)解题报告相关推荐

  1. 第八届“图灵杯”NEUQ—ACM程序设计竞赛个人赛(同步赛)

    A题--切蛋糕 龙龙有一块蛋糕,现在他想将蛋糕平均切成k块,分给他的k名hxd.但是不幸的是,因为龙龙不擅长切蛋糕,他每一次只能将一块蛋糕平均分成两份.例如,将一块大小为1的蛋糕分割成两块大小为1/2 ...

  2. 【Java/总结/牛客/ACM赛制】 “中国东信杯”广西大学第四届程序设计竞赛(同步赛)

    文章目录 题目链接 知识一览 题目列表 快输 F Antinomy与金手指(kmp) H Antinomy与法术威力(队列/区间最值) 题目链接 "中国东信杯"广西大学第四届程序设 ...

  3. 第十八届西南科技大学ACM程序设计竞赛(同步赛)签到题 6题

    文章目录 B 为欢几何 F 青山隐隐,败叶萧萧 G 几番烟雾,只有花难护 H 岸风翻夕浪,舟雪洒寒灯 L 夜暗方显万颗星,灯明始见一缕尘 M 劝君终日酩酊醉,酒不到刘伶坟上土 B 为欢几何 链接:ht ...

  4. ICPC 山东省省赛刷题 第十八届西南科技大学ACM程序设计竞赛(同步赛)牛客 BFH题解

    B 为欢几何 题意:输入n个字符串,输出n个字符,分别是每个字符串的首字母. 分析:直接使用二维数组输入输出即可. 题解: #include<bits/stdc++.h> using na ...

  5. 华中农业大学第五届程序设计大赛网络同步赛解题报告2(转)

    今天实在累了,还有的题晚点补.... 题目链接:http://acm.hzau.edu.cn/problemset.php?page=3 题目:acm.hzau.edu.cn/5th.pdf A:Li ...

  6. [置顶]2010年东北大学ACM程序设计竞赛冬季校赛题解

    8题只做出4题比较easy的题,而且做得挺麻烦,看来还要多练练. AC的题如下 NEUOJ  1112 I Love Apple Description So many people love app ...

  7. E-捡贝壳 2021年广东工业大学第十五届文远知行杯程序设计竞赛(同步赛)

    E-捡贝壳 2021年广东工业大学第十五届文远知行杯程序设计竞赛(同步赛) 小明来到一片海滩上,他很喜欢捡贝壳,但他只喜欢质量为x的倍数的贝壳. 贝壳被排列成一条直线,下标从1到n编号,小明打算从编号 ...

  8. 中国石油大学(北京)第三届“骏码杯”程序设计竞赛(同步赛)——C 小菲爱数数

    题目链接:C-小菲爱数数_中国石油大学(北京)第三届"骏码杯"程序设计竞赛(同步赛) (nowcoder.com) 思路好像和题解不一样,但是a了. 主要思路:首先肯定是要先把素数 ...

  9. 2020年广东工业大学第十届文远知行杯新生程序设计竞赛(同步赛)G.排解忧伤

    2020年广东工业大学第十届文远知行杯新生程序设计竞赛(同步赛)G.排解忧伤 题目链接 题目描述 猪猪参加小米赞助的icpc比赛之后惨遭打铁,为了排解忧伤,他开始观察嘉宾席. 嘉宾席是间隔为1,一字排 ...

  10. G-分割 2021年广东工业大学第十五届文远知行杯程序设计竞赛(同步赛)

    G-分割 2021年广东工业大学第十五届文远知行杯程序设计竞赛(同步赛) 在一个二维平面, 有n条平行于y轴的直线, 他们的x坐标是x[i], m条平行于x轴的直线y[i],他们的y坐标是y[i]. ...

最新文章

  1. jQuery 一次定时器_干货 | 小论定时器玩法(时间轮询法)
  2. 再见SpringMVC!小程序开发工程师岗位职责
  3. C语言经典程序之:求十个整数中的最大最小数并输出(指针)
  4. S5PV210开发 -- 前言
  5. OpenWindow.document.write();
  6. Android 广播接收
  7. 求一个任意实数c的算术平方根g_中考总复习实数知识点
  8. HDU1171-Big Event in HDU
  9. 构建基于Hibernate的servlet(1)
  10. 人工智能必备知识储备之“数学篇”
  11. iOS - AVAudioSession详解
  12. 百度云离线下载含有违规内容检测方法分析
  13. 基于Mono.Cecil的静态注入
  14. AR小项目的制作过程(一)
  15. matlab主成分分析代码
  16. ESP32控制器使用SX1278 LoRa模块的方法
  17. 无人机航测技术的优势有哪些?
  18. python运维是做什么的_Python运维工程师主要干什么?
  19. 2017年小老虎博客排名与访问量备忘录
  20. 人工智能-动物识别系统

热门文章

  1. LeetCode:二进制手表【401】
  2. bzoj3195 [Jxoi2012]奇怪的道路——状压DP
  3. 将一个java工程导入到myeclipse应该注意的地方
  4. CPU结构与指令执行过程简介
  5. 教你遇事最有水平的处理方法
  6. 6、使用infowindow
  7. Linux shell脚本 遍历带空格的文件名
  8. 删除list中的一个节点
  9. 【2021新版】一线大厂 Go 面试题合集
  10. 想领取开发套件,就来参加AIoT开发者大赛