#P00573. 冲锋&&#P00574. 冲锋2

本文探讨了如何判断一个整数是否能被分解为连续正整数之和,并提供了具体的算法实现。对于能够分解的情况,进一步研究了如何找出所有可能的分解方案。

一,#P00573. 冲锋

Description

J将军正在组织他手下的士兵攻击敌人。J将军发现不能让所有的士兵一次性压上。而是应该分成若干个梯队,这些梯队的人数最好形成连续的正整数。例如当他手下有15个士兵时。他应该有以下几种分法

15=1+2+3+4+5

15=4+5+6

15=7+8

但他同时也发现如果手上只有4个士兵时,则无法进行这样的分解。 现在给出J将军手下的士兵人数N,请问他能不能进行分解

Format

Input

一行给出数字N

Output

如果能分解就输出“YES”,否则输出"NO"

Samples

输入数据 1

15

Copy

输出数据 1

YES

二,题目意思分析

意思就是给你一个数字,请问它能否成为一个公差为1的等差数列之和。


三,思路 

结论:2的次方一定不可以,其他的都可以。

有两种可能:

1.如果n是奇数   那么是绝对能进行分解的,因为奇数可以看成是2*n+1,也可以看成是n+(n+1)

2.如果n是偶数   如10,10可以分为2*5.其中5为奇数,2*5的乘法说明了10可以分为两组数,每组和为5,即2和3,1和4;又如98,98=2*49=2*7*7=14*7,提示其可分为4组,每组平均值为14,即11,12,13,14,15,16,17,以此类推,只要一个不能写成若干奇数与偶数相乘之积的形式的数就不可以进行分解,也就是能写成若干个2相乘的形式的数就不可以


四,代码

#include <bits/stdc++.h>
using namespace std;
int n,t,g;
int main()
{
  cin>>n;
  while(n % 2 == 0) n /= 2;
  if(n == 1) cout<<"NO";
  else cout<<"YES";
  return 0;
}







 一, #P00574. 冲锋2

Description

J将军正在组织他手下的士兵攻击敌人。J将军发现不能让所有的士兵一次性压上。而是应该分成若干个梯队,这些梯队的人数最好形成连续的正整数。例如当他手下有15个士兵时。他应该有以下几种分法

15=1+2+3+4+5

15=4+5+6

15=7+8

但他同时也发现如果手上只有4个士兵时,则无法进行这样的分解。 现在给出J将军手下的士兵人数N,请问他能不能进行分解,如果可以则输出分解的方案

Format

Input

一个正整数

Output

输出符合题目描述的全部正整数序列 每行一个序列,每个序列都从该序列的最小正整数开始、以从小到大的顺序打印。 如果结果有多个序列,按各序列的最小正整数的大小从小到大打印各序列。 此外,序列不允许重复,序列内的整数后面有一个空格。如果没有符合要求的序列,输出 "NONE"。

Samples

输入数据 1

15


Copy

输出数据 1

1 2 3 4 5 
4 5 6 
7 8

 二,分析题意

可以看出,这道题就是上一题的举一反三,因为它还让我们输出所有方案。


三,思路

首先,无解的情况判断和上题一样

因为等差数列求和公式为(头+尾) *个数/ 2,答案为输入的数n
那么相当于知道n,求有没有头,尾,个数可以满足上述公式。
但枚举头,尾,个数求是否等于会超时
所以在这里因为该数列公差一定为1, 所以尾=头+个数-1
代入公式,得到(2*头+个数-1)*个数/ 2=n
但是如果枚举头和个数时间复杂度为O(n^2),仍会超时,所以要继续推
我们在这里是已知n的,那么可否通过n和个数推出头呢?
将前面的公式解括号变成(2*头*个数+个数^2一个数) / 2=n
再变成头*个数+ (个数^2/2-个数/ 2)=n
头*个数=n-个数^2/ 2+个数/ 2
头= (n-个数^2/2 +个数/2) /个数
(n-个数^2/ 2 +个数/ 2)/个数=头
那么,我们就只需枚举个数,就可求出头,也就可以求出等差数列的和以及判断和是否为n等操作了。


四,代码

#include <bits/stdc++.h>
using namespace std;
int n,t,op;
vector<int>vec[100001];
int main()
{
  cin>>t;
  n = t;
  while(t % 2 == 0) t /= 2;
  if(t == 1) cout<<"NONE";//无解
  for(int g = 1; g <= n; g++)//枚举等差数列数字个数
  {
    t = (n - (g * g) / 2 + g / 2) / g;//求出头
    int w = t + g - 1;//求出尾
    if(t == 0 || t >= n) continue;//头不能为0,也不能>=n
    int p = (t + w) * g / 2;//求出等差数列的和
    if(p == n)//如果等差数列的和等于n,说明找到了一个解
    {
      for(int k = t; k <= t + g - 1; k++) vec[op].push_back(k);//存进解数组中
      op++;
    }
    else if(p > n) break;//剪枝
  }
  for(int i = op - 1; i >= 0; i--)//输出结果
  {
    for(int j = 0; j < vec[i].size(); j++)
      cout<<vec[i][j]<<" ";
    cout<<endl;
  }
  return 0;
}

import random import tkinter as tk from math import sin, cos, pi, log from tkinter import Tk, Canvas from PIL import Image, ImageTk # 获取屏幕分辨率 root = Tk() SCREEN_WIDTH = root.winfo_screenwidth() SCREEN_HEIGHT = root.winfo_screenheight() root.destroy() # 画布尺寸设为屏幕大小 CANVAS_WIDTH = SCREEN_WIDTH CANVAS_HEIGHT = SCREEN_HEIGHT CANVAS_CENTER_X = CANVAS_WIDTH / 2 CANVAS_CENTER_Y = CANVAS_HEIGHT / 2 IMAGE_ENLARGE = 18 # 增大放大比例,让爱心更大 # 蓝色渐变相关颜色定义 HEART_COLORS = [ "#0000CD", # 中蓝色 "#1E90FF", # 道奇蓝 "#87CEEB", # 天蓝色 "#B0E2FF", # 亮天蓝色 ] # 要显示的文字列表 TEXT_LIST = [ "他不折磨别人只折磨自己", "他喜欢装成熟", "年年康乐,岁岁满全", "我觉得我的十八岁有点逆生长", "不要不开心,你做什么选择做什么决定我都支持你", "逆生长的18岁是23岁的同频,23岁的你是给我18岁的回礼", "你可以演我小弟啊 我当大哥罩着你", "有任何事情冲我来就可以", "真心换真心", "宝宝你是我最可爱的宝宝", "获得了一段真挚的关系", "凌晨的经济舱 为爱冲锋的勋章!", "缘为冰,我把他抱在怀里 冰化了,才发现缘分还在", "其实,该说的都说过了", "我送你三千万,千万要开心,千万要健康,千万要平安", "不要伤害一直以来无私帮助我的人" ] # 存储已显示的文字ID displayed_texts = [] # 当前显示的文字索引 current_text_index = 0 def heart_function(t, shrink_ratio: float = IMAGE_ENLARGE): """爱心函数生成器""" x = 16 * (sin(t) ** 3) y = -(13 * cos(t) - 5 * cos(2 * t) - 2 * cos(3 * t) - cos(4 * t)) x *= shrink_ratio y *= shrink_ratio # 移到画布中央 x += CANVAS_CENTER_X y += CANVAS_CENTER_Y return int(x), int(y) def scatter_inside(x, y, beta=0.15): """在爱心内部随机散布点""" ratio_x = -beta * log(random.random()) ratio_y = -beta * log(random.random()) dx = ratio_x * (x - CANVAS_CENTER_X) dy = ratio_y * (y - CANVAS_CENTER_Y) return x - dx, y - dy def shrink(x, y, ratio): """缩小效果""" force = -1 / (((x - CANVAS_CENTER_X) **2 + (y - CANVAS_CENTER_Y)** 2) **0.6) dx = ratio * force * (x - CANVAS_CENTER_X) dy = ratio * force * (y - CANVAS_CENTER_Y) return x - dx, y - dy def curve(p): """辅助曲线函数,控制爱心跳动的节奏""" return 2 * (2 * sin(4 * p)) / (2 * pi) class Heart: """爱心类,负责生成爱心的各种点集并处理动画效果""" def __init__(self, generate_frame=20): self._points = set() # 原始爱心点 self._edge_diffusion_points = set() # 边缘扩散点 self._center_diffusion_points = set() # 中心扩散点 self.all_points = {} # 所有点的集合,按帧存储 self.build(3000) # 增加点的数量 self.random_halo = 1000 self.generate_frame = generate_frame for frame in range(generate_frame): self.calc(frame) def build(self, number): # 生成基础爱心点 for _ in range(number): t = random.uniform(0, 2 * pi) x, y = heart_function(t) self._points.add((x, y)) # 爱心内扩散 for _x, _y in list(self._points): for _ in range(3): x, y = scatter_inside(_x, _y, 0.05) self._edge_diffusion_points.add((x, y)) point_list = list(self._points) for _ in range(6000): # 增加中心扩散点数量 x, y = random.choice(point_list) x, y = scatter_inside(x, y, 0.17) self._center_diffusion_points.add((x, y)) @staticmethod def calc_position(x, y, ratio): # 计算位置,添加随机抖动 force = 1 / (((x - CANVAS_CENTER_X) **2 + (y - CANVAS_CENTER_Y)** 2) **0.520) dx = ratio * force * (x - CANVAS_CENTER_X) + random.randint(-1, 1) dy = ratio * force * (y - CANVAS_CENTER_Y) + random.randint(-1, 1) return x - dx, y - dy def calc(self, generate_frame): ratio = 10 * curve(generate_frame / 10 * pi) # 跳动的比例 halo_radius = int(4 + 6 * (1 + curve(generate_frame / 10 * pi))) halo_number = int(5000 + 7000 * abs(curve(generate_frame / 10 * pi) **2)) # 增加光环点数量 all_points = [] # 光环效果 heart_halo_point = set() for _ in range(halo_number): t = random.uniform(0, 2 * pi) x, y = heart_function(t, shrink_ratio=18.6) # 增大光环尺寸 x, y = shrink(x, y, halo_radius) if (x, y) not in heart_halo_point: heart_halo_point.add((x, y)) x += random.randint(-14, 14) y += random.randint(-14, 14) size = random.choice((1, 2, 2)) all_points.append((x, y, size)) # 轮廓点 for x, y in self._points: x, y = self.calc_position(x, y, ratio) size = random.randint(1, 3) all_points.append((x, y, size)) # 边缘扩散点 for x, y in self._edge_diffusion_points: x, y = self.calc_position(x, y, ratio) size = random.randint(1, 2) all_points.append((x, y, size)) # 中心扩散点 for x, y in self._center_diffusion_points: x, y = self.calc_position(x, y, ratio) size = random.randint(1, 2) all_points.append((x, y, size)) self.all_points[generate_frame] = all_points def render(self, render_canvas, render_frame): """渲染爱心,使用蓝色渐变""" frame_points = self.all_points[render_frame % self.generate_frame] total_points = len(frame_points) # 根据点在列表中的位置分配不同的蓝色 for i, (x, y, size) in enumerate(frame_points): # 确保点在画布范围内 if 0 <= x < CANVAS_WIDTH and 0 <= y < CANVAS_HEIGHT: color_index = int((i / total_points) * len(HEART_COLORS)) color = HEART_COLORS[min(color_index, len(HEART_COLORS) - 1)] render_canvas.create_rectangle(x, y, x + size, y + size, width=0, fill=color, tags="heart") def add_orderly_text(canvas): """按顺序添加文字到画布""" global current_text_index # 检查是否还有未显示的文字 if current_text_index < len(TEXT_LIST): # 获取当前要显示的文字 text = TEXT_LIST[current_text_index] # 随机位置(确保在屏幕范围内) x = random.randint(50, CANVAS_WIDTH - 50) y = random.randint(50, CANVAS_HEIGHT - 50) # 随机字体大小 font_size = random.randint(12, 24) # 创建文字并保存ID text_id = canvas.create_text( x, y, text=text, fill="white", font=("SimHei", font_size), tags="text" ) displayed_texts.append(text_id) # 索引加1,准备显示下一个文字 current_text_index += 1 # 1秒后再次添加文字 canvas.after(1000, add_orderly_text, canvas) def draw(main: Tk, render_canvas: Canvas, render_heart: Heart, render_frame=0): """绘制函数,负责每一帧的绘制和动画更新""" # 只清除爱心相关元素,保留文字 render_canvas.delete("heart") # 绘制背景图片 if background_image_tk: render_canvas.create_image(CANVAS_WIDTH / 2, CANVAS_HEIGHT / 2, image=background_image_tk, tags="heart") # 绘制爱心(添加heart标签) render_heart.render(render_canvas, render_frame) # 更新帧 main.after(160, draw, main, render_canvas, render_heart, (render_frame + 1) % render_heart.generate_frame) if __name__ == '__main__': root = Tk() root.title("全屏跳动的爱心与文字") root.attributes('-fullscreen', True) # 设置为全屏模式 root.bind("<Escape>", lambda e: root.destroy()) # 按ESC键退出全屏 # 加载背景图片并调整为屏幕大小 background_image_tk = None try: # 请将此路径替换为你自己的图片路径 background_image = Image.open("sea.png") # 调整图片大小以适应屏幕 background_image = background_image.resize((CANVAS_WIDTH, CANVAS_HEIGHT), Image.LANCZOS) background_image_tk = ImageTk.PhotoImage(background_image) except Exception as e: print(f"无法加载背景图片: {e}") print("将使用黑色背景") canvas = Canvas(root, bg='black', height=CANVAS_HEIGHT, width=CANVAS_WIDTH) canvas.pack() heart = Heart() # 添加说明文字 if background_image_tk: canvas.create_text(CANVAS_WIDTH / 2, CANVAS_HEIGHT - 30, text="爱心跳动中... 文字将按顺序出现并保留... 按ESC键退出", fill="white", font=("SimHei", 14), tags="text") # 开始按顺序添加文字 add_orderly_text(canvas) # 开始绘制 draw(root, canvas, heart) root.mainloop()修改代码,使文字按顺序出现,并只出现一次,文字出现后不消失
07-07
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值