AcWing 4299. 删点
题目链接:AcWing 4299. 删点
第一题都是签到题,其实就是计算是否存在在y轴两边,是否有一边的点数小于等于1
代码如下:
#include <iostream>
using namespace std;
const int N = 110;
int n, l, r;
int main(){
cin >> n;
for(int i = 0; i < n; i++){
int x, y;
cin >> x >> y;
if(x > 0)r++;
else l++;
}
if(l <= 1 || r <= 1)puts("Yes");
else puts("No");
return 0;
}
AcWing 4300. 两种操作
题目链接:AcWing 4300. 两种操作
这道题其实并不难,只要找对了方向就好做了,他只有两个操作,即减1和乘2,反过来就相当于对m进行两种操作,即通过加1和除2得到n,为了能够令m更快的接近n,很明显我们需要通过先除法来进行操作,当m小于n时,我们在进行加法,但是在这个过程中,m可能为奇数,所以我们需要判断,当m位奇数时,需对其加1,以保证能整除,最后得到n。
当然还有一种情况,就是当n > m时,这是n只能通过减1的方式得到m,所以这种情况直接计算n - m即可。
代码如下:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int n, m, res;
int mid(){
int k = 0;
while(m > n){// 当m <= n时说明m已经很接近n且可以通过加一的操作得到n了
if(m % 2){ //判断m是否为奇数
m++;
res++;//res用来计算中途+1的操作次数
}
m /= 2;
k++;//k计算除2的操作次数
}
return k;
}
int main(){
cin >> n >> m;
if (n == m)cout << 0 << endl;//情况1: n == m
else if(n > m) //情况2: n > m
cout << n - m << endl;
else{ //情况3: n < m
int b = m;
int k = mid(); //因为除2的过程有点像二分,所以我取名为mid
if(m == n)cout << k + res << endl; // 如果恰好等于则不需要再进行加1操作
else if(m < n)cout << (n - m) + k + res << endl; // 否则还需加上最后加1的操作
}
return 0;
}
AcWing 4301. 截断数列
题目链接:AcWing 4301. 截断数列
这道题虽是困难题,但其实也并不算太难,方向还是很好想到的,就是编程实现的方法不同可能会遇到一些麻烦,就比如说将其转化为数字并用数组存储,这样就要处理一些特殊情况,实际上并不需要转换,直接用字符串的形式,它们对应的ASCLL码值计算也是一样的。
思路:
其实将其分成两组或两组以上和的大小相同的形式,我们很容易可以考虑到,先将它们的总和计算,然后在更具总和的因子进行分组即可,因为不能随便分,顺序还是一样的,所以我们对每个因子的情况对字符串进行遍历,如果能够组成这个数,那就可以。
代码如下:
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 110;
int n, sum;
char s[N];
int main(){
cin >> n >> s;
for(int i = 0; i < n; i++){
s[i] -= '0';
sum += s[i];
}
for(int i = 2; i <= n; i++){
if(sum % i == 0){//判断是否是因子
int k = 0;
int p = sum / i;
bool f = true;
//遍历,查看是否能分成等分
for(int j = 0; j < n; j++){
k += s[j];
//如果k已经大于p则说明不能,直接退出,并标记false
if(k > p){
f = false;
break;
}
else if(k == p){//如果等于则归0,重新开始计算
k = 0;
}
}
if(f){
puts("YES");
return 0;
}
}
}
puts("NO");
return 0;
}