题目链接:AcWing 4299. 删点
第一题都是签到题,其实就是计算是否存在在y轴两边,是否有一边的点数小于等于1
代码如下:
#includeAcWing 4300. 两种操作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. 两种操作
这道题其实并不难,只要找对了方向就好做了,他只有两个操作,即减1和乘2,反过来就相当于对m进行两种操作,即通过加1和除2得到n,为了能够令m更快的接近n,很明显我们需要通过先除法来进行操作,当m小于n时,我们在进行加法,但是在这个过程中,m可能为奇数,所以我们需要判断,当m位奇数时,需对其加1,以保证能整除,最后得到n。
当然还有一种情况,就是当n > m时,这是n只能通过减1的方式得到m,所以这种情况直接计算n - m即可。
代码如下:
#includeAcWing 4301. 截断数列#include #include #include 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. 截断数列
这道题虽是困难题,但其实也并不算太难,方向还是很好想到的,就是编程实现的方法不同可能会遇到一些麻烦,就比如说将其转化为数字并用数组存储,这样就要处理一些特殊情况,实际上并不需要转换,直接用字符串的形式,它们对应的ASCLL码值计算也是一样的。
思路:
其实将其分成两组或两组以上和的大小相同的形式,我们很容易可以考虑到,先将它们的总和计算,然后在更具总和的因子进行分组即可,因为不能随便分,顺序还是一样的,所以我们对每个因子的情况对字符串进行遍历,如果能够组成这个数,那就可以。
代码如下:
#include#include #include #include 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; }



