T1 立方数

题目

【题目描述】

作为XX战队的狂热粉丝,MdZzZZ看到了自己心仪的队伍在半决赛落败,顿时心灰意冷。看着自己手中的从黄牛那里抢来的天价总决赛门票,MdZzZZ觉得去鸟巢已经没有意义了,于是他决定去跳“水立方”。在他准备进“水立方”体育馆时,一位大妈拦住了他的去路,并产生了一下对话:

大妈:“年轻人我看你印堂发黑,恕我冒昧直言,此去一行怕是会有什么不测。”

MdZzZZ:“大妈别拦我,我要跳水立方发泄一下!”

大妈:“年轻人,做事要三思而后行,你知道这水立方最著名的是什么吗?”

MdZzZZ:“不知...”

大妈:“这水立方最有名的是‘立方数’!”

MdZzZZ:“哦?”

大妈:“别急,听我细细道来。‘立方数’就是,如果一个数可以被写作是一个正整数的3次方,则这个数就是立方数。例如1,8,27就是最小的3个立方数。”

MdZzZZ:“……”

大妈:“当然,想要在这水立方中来去自如,你需要知道‘立方差数’!”

大妈:“若一个数可以被写作是两个立方数的差,则这个数就是‘立方差数’,例如7(8-1),26(27-1),19(27-8)都是立方差数。如果你能够判断随便一个数是不是‘立方差数’,那么你就可以真正地在这一片小天地中当一条无忧无虑的小鱼...”

未等MdZzZZ反应过来,大妈以飘然远去,留下他一个人在那边细细思索。那么现在你的问题来了,你需要帮助MdZzZZ解决这个问题。

现在给定一个数P,MdZzZZ想要知道这个数是不是立方差数。

当然你有可能随机输出一些莫名其妙的东西,因此MdZzZZ有T次询问~

这个问题可能太难了…… 因此MdZzZZ规定P是个质数!

【输入格式】

第一行一个数T,表示有T组数据。

接下来T行,每行一个数P。

【输出格式】

输出T行,对于每个数如果是立方差数,输出“YES”,否则输出“NO”。

【输入样例】

5

2

3

5

7

11

【输出样例】

NO

NO

NO

YES

NO

【数据规模】

对于30%的数据p<=100。

对于60%的数据p<=10^6。

对于100%的数据p<=10^12,T<=100。

解析

嗯......题目很长,去掉废话,实际上就是要求质数p是不是立方差数(立方数即为a3-b3(a,b均为正整数,且a≠b)。

我们尝试化简一下a3-b3=p这个式子,可以得到(a-b)(a2+ab+b2)=p,因为p是质数,根据质数的定义(只有1和它本身是它的因数)可以得到,a-b与a2+ab+b2其中一个为1,

很显然a2+ab+b2不为1(因为a与b为互不相等的正整数),所以a-b=1,移项得a=b+1,带入a3-b3=p,得

(b+1)3-b3=p,即b3+3b2+3b+1-b3=p,化简并移项得3b2+3b+1-p=0,显然,这是一个一元二次方程,解这个方程可得,

b=(-3±sqrt(12p-3))/6(sqrt为求根号函数),由于b是正整数,所以如果-3±sqrt(12p-3)可以整除6的话,p就是立方差数。

由于p≤10^12,所以要记得开long long(本蒟蒻就是没开long long少了40分QAQ)。

Code

#include <algorithm>
#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
long long read()
{
long long num=,w=;
char ch=getchar();
while(ch<''||ch>'')
{
if(ch=='-') w=-;
ch=getchar();
}
while(ch>=''&&ch<='')
{
num=(num<<)+(num<<)+ch-'';
ch=getchar();
}
return num*w;
}
int T;
long long p;
double a;
int main()
{
//freopen("cubicp.in","r",stdin);
//freopen("cubicp.out","w",stdout);
T=read();
while(T--)
{
p=read();
a=(sqrt(*p-)-)-(long long)(sqrt(*p-)-);
if(a==&&(long long)(sqrt(*p-)-)%==) cout<<"YES"<<endl;
else cout<<"NO"<<endl;
}
return ;
//fclose(stdin);
//fclose(stdout);
}

T2 二叉树

题目

【题目描述】

从前有一棵二叉树,我们用如下方式来表示这棵二叉树。

(1)如果一个节点没有儿子,我们用“0”来表示他。

(2)如果一个节点有一个儿子,我们对它的表示以“1”开头,后面接对它儿子的表示。

(3)如果一个节点有两个儿子,我们对它的表示以“2”开头,后面先接对它左儿子的表示,后接对它右儿子的表示。

KJDH十分贪玩,将这棵树染了色,KJDH又十分聪明,它染色又很有规则:每个节点不能和它的孩子有相同的颜色,如果一个节点有两个孩子,那么这两个孩子也不能有相同的颜色。

由于这个树年代久远了,所以我们看不清每个节点的颜色了,但我们知道KJDH只染了红黄白三种颜色。我们想知道这棵树最多和最少有多少个节点是白色的。

【输入格式】

输入文件只有一行,一个字符串,只有“0”,“1”,“2”组成,表示这棵树的结构。

【输出格式】

输出文件包含两个用空格隔开的数,分别表示白色节点的最多和最少数量。

【输入样例】

200

【输出样例】

1 1

【数据规模】

对于 20% 的数据,len<=10。

对于 50% 的数据,len<=2000

对于 100% 的数据,len<=500000。其中len为读入字符串的长度。

解析

不想说话,直接上大佬题解(手动滑稽):

Code

#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int MAXN = ;
int f[MAXN][], g[MAXN][];
int n, m, i, j, len, k, lc[MAXN], rc[MAXN];
char s[MAXN];
inline int maketree(int x)
{
if (x > len) return ;
if (s[x] == '') return x;
if (s[x] == '') {lc[x] = ++n; return maketree(x + );}
if (s[x] == '') {lc[x] = ++n; int nex = maketree(x + ); rc[x] = ++n; return maketree(nex + );}
}
inline void dp(int now)
{
f[now][] = g[now][] = ;
if (lc[now] && !rc[now])
{
dp(lc[now]);
f[now][] += max(f[lc[now]][], f[lc[now]][]);
f[now][] += max(f[lc[now]][], f[lc[now]][]);
f[now][] += max(f[lc[now]][], f[lc[now]][]);
g[now][] += min(g[lc[now]][], g[lc[now]][]);
g[now][] += min(g[lc[now]][], g[lc[now]][]);
g[now][] += min(g[lc[now]][], g[lc[now]][]);
}
if (lc[now] && rc[now])
{
dp(lc[now]); dp(rc[now]);
f[now][] += max(f[lc[now]][] + f[rc[now]][], f[lc[now]][] + f[rc[now]][]);
f[now][] += max(f[lc[now]][] + f[rc[now]][], f[lc[now]][] + f[rc[now]][]);
f[now][] += max(f[lc[now]][] + f[rc[now]][], f[lc[now]][] + f[rc[now]][]);
g[now][] += min(g[lc[now]][] + g[rc[now]][], g[lc[now]][] + g[rc[now]][]);
g[now][] += min(g[lc[now]][] + g[rc[now]][], g[lc[now]][] + g[rc[now]][]);
g[now][] += min(g[lc[now]][] + g[rc[now]][], g[lc[now]][] + g[rc[now]][]);
}
}
int main()
{
//freopen("tree.in", "r", stdin);
//freopen("tree.out", "w", stdout);
scanf("%s", s + );
len = strlen(s + );
n = ;
maketree();
dp();
cout << max(f[][], max(f[][], f[][])) << " " << min(g[][], min(g[][], g[][])) << endl;
}

T3 Hanoi

题目

【题目描述】

众所周知, 汉诺塔是一个古老又经典的游戏. 这个游戏是这样的, 你有N个大小不同的盘子和3根柱子, 一开始所有盘子都叠放在第1根柱子上, 你需要把N个盘子全都移动到第3根柱子上, 每次都可以选择某根柱子最上面的盘子移动到另一根柱子上, 但是任何时候都必须保证没有一个盘子上面放了一个比它大的盘子. 求最少的移动步数.

这个问题太简单了, 乐于寻找挑战的你想要求出当有N个盘子, M个柱子且其他条件不变时, 把所有盘子从第1根柱子移动到第M根柱子的最少步数.

【输入格式】

一行两个整数分别代表题目中的N, M.

【输出格式】

一行一个整数代表答案.

【输入样例】

5 3

【输出样例】

31

【数据规模】

对于10%的数据, N <= 20, M = 3.

对于30%的数据, M = 3.

对于50%的数据, M <= 4.

对于100%的数据, N <= 63, 3 <= M <= N + 1;

解析

每天必不可少的DP题,令f[i][j]表示i个盘子j个柱子时的最少步数,怎样移动会是最少步数呢?

先把上面盘子移动到不是j的柱子上,再把剩下的盘子移动到j的柱子上,再把上面的盘子移动到j的柱子上。

递推式:f[i][j] = min(f[k][j] * 2 + f[i - k][j - 1])。

Code

#include <algorithm>
#include <iostream>
#include <cstring>
#include <string>
#include <cstdio>
#include <cmath>
using namespace std;
int read()
{
int num=,w=;
char ch=getchar();
while(ch<''||ch>'')
{
if(ch=='-') w=-;
ch=getchar();
}
while(ch>=''&&ch<='')
{
num=(num<<)+(num<<)+ch-'';
ch=getchar();
}
return num*w;
}
int n,m;
long long f[][];
int main()
{
//freopen("hanoi.in","r",stdin);
//freopen("hanoi.out","w",stdout);
memset(f,0x7f7f7f7f,sizeof(f));
n=read(),m=read();
for(int i=;i<=m;i++) f[][i]=,f[][i]=;
for(int i=;i<=n;i++) f[i][]=*f[i-][]+;
for(int i=;i<=n;i++)
for(int j=;j<=m;j++)
for(int k=;k<i;k++) f[i][j]=min(f[i][j],*f[k][j]+f[i-k][j-]);
cout<<f[n][m];
return ;
//fclose(stdin);
//fclose(stdout);
}

T4 区间

题目

【题目描述】

有一个 n 个数的序列,一开始所有的数都是 0,每次可以将一个区间 [l,r](l ≤ r) 内的数 +1,求到达最 终状态的最少操作次数

【输入格式】

第一行包含一个正整数 n,表示序列的长度。

第二行包含 n 个不同的正整数 a1,a2,...,an,表示最终的状态。

【输出格式】

输出的第一行是一个正整数 m,表示最少的操作次数。 接下来 m 行每行两个正整数 li,ri,表示一次操作。你需要保证 1 ≤ li ≤ ri ≤ n。 保证最少次数 m ≤ 105,输出可以以任意顺序输出。

【输入样例】

2

8 8

【输出样例】

8

1 2

1 2

1 2

1 2

1 2

1 2

1 2

1 2

【数据规模】

解析

本蒟蒻只会O(nm)做法,直接上大佬题解吧:

Code

#include <algorithm>
#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
int read()
{
int num=,w=;
char ch=getchar();
while(ch<''||ch>'')
{
if(ch=='-') w=-;
ch=getchar();
}
while(ch>=''&&ch<='')
{
num=(num<<)+(num<<)+ch-'';
ch=getchar();
}
return num*w;
}
int n,a[],d1[],d2[],temp;
void work(int l,int r,int lastmin)
{
for(int i=;i<=lastmin;i++) d1[++temp]=l,d2[temp]=r;
int nowmin=0x7f7f7f7f,ll=;
for(int i=l;i<=r;i++) a[i]-=lastmin;
for(int i=l;i<=r;i++)
if(a[i]==)
{
if(ll==) ll=i+;
else
{
if(ll>i-) continue;
for(int j=ll;j<=i-;j++) nowmin=min(nowmin,a[j]);
work(ll,i-,nowmin);
nowmin=0x7f7f7f7f,ll=i+;
}
}
else if(i==l) ll=l;
else if(i==r)
{
for(int j=ll;j<=r;j++) nowmin=min(nowmin,a[j]);
work(ll,r,nowmin);
}
}
int main()
{
//freopen("range.in","r",stdin);
//freopen("range.out","w",stdout);
n=read();
int nowmin=0x7f7f7f7f,ll=;
for(int i=;i<=n;i++) a[i]=read();
if(n==)
{
cout<<a[]<<endl;
for(int i=;i<=a[];i++) cout<<"1 1"<<endl;
return ;
}
work(,n,);
cout<<temp<<endl;
for(int i=;i<=temp;i++) cout<<d1[i]<<" "<<d2[i]<<endl;
return ;
//fclose(stdin);
//fclose(stdout);
}

O(nm)做法(69分)

#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int MAXN = ;
int sum[MAXN << ], cnt[MAXN << ];
int n, m, i, j, k, l, r, ans, a[MAXN], tot;
inline int get()
{
char c;
while ((c = getchar()) < || c > );
int res = c - ;
while ((c = getchar()) >= && c <= )
res = res * + c - ;
return res;
}
inline void updata(int k)
{
sum[k] = min(sum[k << ], sum[k << | ]);
}
inline void putdown(int k)
{
if (cnt[k])
{
cnt[k << ] += cnt[k];
cnt[k << | ] += cnt[k];
sum[k << ] -= cnt[k];
sum[k << | ] -= cnt[k];
cnt[k] = ;
}
}
inline void change(int k, int p, int q, int l, int r)
{
if (p >= l && q <= r)
{
cnt[k] ++;
sum[k] --;
return;
}
putdown(k);
int mid = p + q >> ;
if (mid >= l) change(k << , p, mid, l, r);
if (mid < r) change(k << | , mid + , q, l, r);
updata(k);
}
inline int query(int k, int p, int q, int w)
{
if (p == q) return sum[k];
putdown(k);
int mid = p + q >> ;
if (mid >= w) return query(k << , p, mid, w);
else return query(k << | , mid + , q, w);
}
inline void maketree(int k, int p, int q)
{
if (p == q)
{
sum[k] = a[p];
return;
}
int mid = p + q >> ;
maketree(k << , p, mid);
maketree(k << | , mid + , q);
updata(k);
}
inline void find(int k, int p, int q, int l, int r)
{
int mid = p + q >> ;
if (tot) return;
putdown(k);
if (p == q) {if (!sum[k]) tot = p; return;}
if (p >= l && q <= r)
{
if (!sum[k << ]) find(k << , p, mid, l, r);
else if (!sum[k << | ]) find(k << | , mid + , q, l, r);
}
else
{
if (mid >= l) find(k << , p, mid, l, r);
if (mid < r) find(k << | , mid + , q, l, r);
}
}
int main()
{
//freopen("range.in", "r", stdin);
//freopen("range.out", "w", stdout);
cin >> n;
for(i = ; i <= n; i ++)
a[i] = get();
for(i = ; i <= n; i ++)
if (a[i] > a[i - ]) ans += a[i] - a[i - ];
cout << ans << endl;
maketree(, , n);
for(i = ; i <= n; i ++)
while (query(, , n, i))
{
tot = ;
find(, , n, i, n);
if (!tot) printf("%d %d\n", i, n), change(, , n, i, n);
else printf("%d %d\n", i, tot - ), change(, , n, i, tot - );
}
}

AC代码

长乐培训Day9的更多相关文章

  1. 长乐培训Day4

    T1 矩阵 题目 [题目描述] 从前有个 n×m 的矩阵,初始时每个位置均为 0.你需要依次执行 q 个操作,每个操作会指定一行或一列,然后将该行或该列的所有元素全部赋为一个相同的值. 输出操作完成后 ...

  2. 长乐培训Day8

    T1 远征 题目 [题目描述] 寒枫将军将要带领他的部队去圣雪山消灭那里的冰龙.部队分成了若干个小队,属于同一个小队的人兵种相同. 寒枫将军有着杰出的指挥能力,在战斗的时候,寒枫将军能够让所有相同兵种 ...

  3. 长乐培训Day7

    T1 删除 题目 [题目描述] 现在,我的手上有 n 个数字,分别是 a1,a2,a3,...,an. 我现在需要删除其中的 k 个数字.当然我不希望随随便便删除,我希望删除 k 数字之后,剩下的 n ...

  4. 长乐培训Day6

    T1 数列 题目 [题目描述] [输入格式] [输出格式] [输入样例] [输出样例] [数据规模] 如上所述. 解析 身为T1,居然比T4还难......让我怎么办......以下为巨佬题解: 我猜 ...

  5. 长乐培训Day5

    T1 圆圈舞蹈 题目 [题目描述] 熊大妈的奶牛在时针的带领下,围成了一个圈跳舞.由于没有严格的教育,奶牛们之间的间隔不一致. 奶牛想知道两只最远的奶牛到底隔了多远.奶牛A到B的距离为A顺时针走和逆时 ...

  6. 长乐培训Day3

    T1 奶牛晒衣服 题目 [题目描述] 在熊大妈英明的带领下,时针和他的同伴生下了许多牛宝宝.熊大妈决定给每个宝宝都穿上可爱的婴儿装.于是,为牛宝宝洗晒衣服就成了很不爽的事情. 圣人王担负起了这个重任. ...

  7. 长乐培训Day2

    T1 足球联赛 题目 [题目描述] 巴蜀中学新一季的足球联赛开幕了.足球联赛有n只球队参赛,每赛季,每只球队要与其他球队各赛两场,主客各一场,赢一场得3分,输一场不得分,平局两只队伍各得一分. 英勇无 ...

  8. 长乐培训Day1

    T1 魔法照片 题目 [题目描述] 如果你看过<哈利·波特>,你就会知道魔法世界里的照片是很神奇的.也许是因为小魔法师佳佳长的太帅,很多人都找他要那种神奇的魔法照片, 而且还都要佳佳和他的 ...

  9. 长乐国庆集训Day5

    T1 方阵 题目 [题目描述] 小澳最近迷上了考古,他发现秦始皇的兵马俑布局十分有特点,热爱钻研的小澳打算在电脑上还原这个伟大的布局. 他努力钻研,发现秦始皇布置兵马俑是有一定规律的.兵马俑阵总共有n ...

随机推荐

  1. select下拉框多选取值

    本来是单选取值,现改为多选 其中<select> 标签新增multiple属性,如<select id = "sel"  multiple = "mul ...

  2. 深度学习面试题28:标签平滑(Label smoothing)

    目录 产生背景 工作原理 参考资料 产生背景 假设选用softmax交叉熵训练一个三分类模型,某样本经过网络最后一层的输出为向量x=(1.0, 5.0, 4.0),对x进行softmax转换输出为: ...

  3. 夺灵者哈卡(Hakkar, the Soulflayer)

    Hakkar, the Soulflayer夺灵者哈卡Deathrattle: Shuffle a Corrupted Blood into each player's deck.亡语:将一张“堕落之 ...

  4. 启用Win10的Linux子系统

    今天为大家介绍如何才能启用Windows10下的Linux子系统,废话不多说,直接看步骤: 启用开发者模式打开设置 点击更新和安全 点击开发者选项 启用开发人员模式 更改系统功能使用win+X快捷键调 ...

  5. Android命名规范(重点讲解:包名)

    Android程序开发中,使用规范的命名有益于程序的开发和后期阅读.本文主要对Android程序包名的定义做详细介绍,并附带一些简单的命名规则. 一.标识符命名方法1 .小驼峰命名法,除首单词外,其余 ...

  6. flutter 权限申请

    添加依赖 permission_handler: ^3.2.2 androidmanifest.xml添加对应的用户权限 在flutter 中app入口申请权限: import 'package:fl ...

  7. ISO/IEC 9899:2011 条款6.2——概念

    6.2 概念 6.2.1 标识符的作用域 6.2.2 标识符的连接 6.2.3 标识符的名字空间 6.2.4 对象的存储持久性 6.2.5 类型 6.2.6 类型的表示 6.2.7 兼容类型与组合类型 ...

  8. selenium grid用法

    一,selenium grid是什么? selenium是一个用于UI自动化测试的工具. selenium grid是selenium家族中的三大组件的一员.selenium grid有两个版本,gr ...

  9. 使用SoapUI发送Post请求

    https://www.cnblogs.com/xiaowangzi1110/p/8544264.html 使用SoapUI发送Post请求 SoapUI作为一个开源的工具,其具备强大的功能.易用的界 ...

  10. Opencv图片明暗处理

    Opencv图片明暗处理 #include <iostream> #include <opencv2/opencv.hpp> using namespace std; usin ...