C. Polygon for the Angle

You are given an angle angang.

The Jury asks You to find such regular nn-gon (regular polygon with nn vertices) that it has three vertices aa, bb and cc (they can be non-consecutive) with ∠abc=ang∠abc=ang or report that there is no such nn-gon.

If there are several answers, print the minimal one. It is guarantied that if answer exists then it doesn't exceed 998244353998244353.

Input

The first line contains single integer TT (1≤T≤1801≤T≤180) — the number of queries.

Each of the next TT lines contains one integer angang (1≤ang<1801≤ang<180) — the angle measured in degrees.

Output

For each query print single integer nn (3≤n≤9982443533≤n≤998244353) — minimal possible number of vertices in the regular nn-gon or −1−1 if there is no such nn.

思路:模拟:最少三个点才能有角度,所以从3开始模拟

#include <bits/stdc++.h>
#define ll long long
#define INF 0x3f3f3f3f
#define mod 998244353
using namespace std;
double n;
int main(){
    int t;
    cin>>t;
    while(t--){
        cin>>n;int i,f=0;
        for(i=3;i<400;i++){
            double du=360.0/i;
            for(int j=1;j<i-1;j++){//i-1表示若分为i份,最多i-2个组成角度
                int a=(int)j*du/2;
                if(a==n){
                    f=1;
                    break;
                }
            }
            if(f)break;
        }
        cout<<i<<endl;
    }
    return 0;
}

使用gcd,求出和180的最大公约数,

#include<bits/stdc++.h>
using namespace std;
int T,n,ans;
int main(){
	cin>>T;
	while(T--){
		cin>>n;
		int zz=__gcd(n,180);
		zz=180/zz;
		while(180*(zz-2)/zz<n) zz*=2;
		cout<<zz<<endl;
	}
	return 0;
}

 

#include <windows.h> #include <math.h> //窗口处理函数WndProc()的声明 LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); POINT CalcPoints(const RECT& rc,int totalSides){ POINT PointArray[16]; const double pi = 3.14159265358979; tagPOINT ptCenter; double dblRadiusx = (rc.right - rc.left) / 2; double dblRadiusy = (rc.bottom - rc.top) / 2; double dblAngle = 3 * pi / 2; double dblDiff = 2 * pi / totalSides; ptCenter.x = (rc.left + rc.right) / 2; ptCenter.y = (rc.top + rc.bottom) / 2; // Calculate thr points for each side for (int i = 0; i < totalSides; i++) { PointArray[i].x = (long)(dblRadiusx + cos(dblAngle) + ptCenter.x + 0.5); PointArray[i].y = (long)(dblRadiusy + sin(dblAngle) + ptCenter.y + 0.5); dblAngle += dblDiff; } return PointArray[16]; } //主函数,程序的入口,相当于之前的main()函数 int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) { static char szAppName[] = "HelloWin"; HWND hwnd; MSG msg; WNDCLASS wndclass;//WNDCLASSEX也行,会多几个分量,配合RegisterClassEX使用 //设置WNDCLASS结构体,为下一步调用RegisterClass()函数做准备 wndclass.style = CS_HREDRAW | CS_VREDRAW;//支持重绘,不能为0 wndclass.lpfnWndProc = (WNDPROC)WndProc;//主函数与窗口处理函数绑定 wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.hInstance = hInstance; wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION); wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); wndclass.lpszMenuName = NULL; wndclass.lpszClassName = szAppName; //注册 if (!RegisterClass(&wndclass)) { MessageBox(NULL, "This program requires Windows NT!", szAppName, MB_ICONERROR); return 0; } //调用CreateWindow()函数创建窗体 hwnd = CreateWindow (szAppName, // window class name "The Windows Program", // window caption WS_OVERLAPPEDWINDOW, // window style CW_USEDEFAULT, // initial x position CW_USEDEFAULT, // initial y position CW_USEDEFAULT, // initial x size CW_US
最新发布
03-08
<think>嗯,用户提供的这段代码看起来是关于Windows API编程的,特别是创建窗口和绘制多边形的部分。首先,我需要仔细分析代码中的问题。看起来用户可能在编写一个Windows应用程序,用来在窗口内绘制一个多边形,比如十六边形或者其他正多边形。 首先,我注意到在CalcPoints函数中,定义了一个POINT数组PointArray[16],然后循环计算每个顶点的位置。不过,函数返回的是PointArray[16],这有问题,因为数组索引从0开始,所以PointArray[16]实际上是第17个元素,这会导致越界访问。而且,返回局部数组的指针或元素会导致未定义行为,因为局部数组在函数结束后会被销毁。因此,这里应该使用动态分配或者将数组作为参数传入。 另外,在CreateWindow调用中,参数部分被截断了,用户可能没有完成代码的编写,导致窗口创建不完整。例如,最后一行有“CW_US”,这可能是CW_USEDEFAULT的未完成部分,需要修正。 接下来,窗口处理函数WndProc的声明存在但未实现,用户可能没有提供这部分代码,导致窗口无法处理消息,比如绘制消息WM_PAINT。因此,程序可能无法正确显示图形。 还有,CalcPoints函数中的半径计算可能有问题。dblRadiusx和dblRadiusy应该是窗口客户区宽度和高度的一半,但计算时直接用了rc.right - rc.left,可能需要考虑客户区坐标是否正确。此外,计算坐标时,用了dblRadiusx + cos(dblAngle)加上中心点,但这里应该是半径乘以cos值,即dblRadiusx * cos(dblAngle),否则当半径较大时,坐标可能不正确。 另外,代码中的totalSides参数被传入CalcPoints,但函数内部固定使用了16个点的数组,这会导致如果totalSides超过16时,数组越界。所以应该根据传入的totalSides动态分配数组大小,或者确保传入的值不超过16。 还有,代码中的tagPOINT结构可能是POINT的别名,但更标准的写法是直接使用POINT结构,可能不需要用tagPOINT。 在WinMain函数中,注册窗口类后,创建窗口时可能缺少了显示窗口的命令,比如ShowWindow(hwnd, iCmdShow)和UpdateWindow(hwnd),虽然用户可能在后续代码中有,但被截断了,需要补充。 最后,消息循环部分可能不完整,用户提供的代码中只有while循环的起始部分,但没有完成消息的处理,比如TranslateMessage和DispatchMessage的调用,这会导致窗口无法正常响应事件。 总结一下,用户代码中存在几个主要问题:CalcPoints函数返回局部数组导致的问题,数组越界,坐标计算错误,窗口创建参数不完整,以及WndProc未实现导致无法处理绘制事件。需要逐一修正这些问题才能使程序正常运行。</think>以下是对代码问题的分析及解决方案: ### 代码问题分析 1. **CalcPoints函数返回局部数组** `return PointArray[16]`存在两个问题: - 数组索引越界(有效索引0-15) - 返回局部变量地址导致未定义行为 2. **CreateWindow参数不完整** 代码末尾`CW_US`应为`CW_USEDEFAULT`,窗口创建参数不完整 3. **坐标计算公式错误** 当前公式: ```c dblRadiusx + cos(dblAngle) + ptCenter.x ``` 正确应为: $$ x = ptCenter.x + dblRadiusx \times \cos(\theta) $$ $$ y = ptCenter.y + dblRadiusy \times \sin(\theta) $$ 4. **未实现WndProc函数** 缺少窗口消息处理函数的具体实现 ### 修正后的关键代码 ```cpp // 修正后的CalcPoints函数 void CalcPoints(POINT* points, const RECT& rc, int totalSides) { const double pi = 3.14159265358979; POINT ptCenter{ (rc.left + rc.right) / 2, (rc.top + rc.bottom) / 2 }; double radiusX = (rc.right - rc.left) / 2.0; double radiusY = (rc.bottom - rc.top) / 2.0; double startAngle = 3 * pi / 2; double angleStep = 2 * pi / totalSides; for (int i = 0; i < totalSides; ++i) { double angle = startAngle + i * angleStep; points[i].x = ptCenter.x + static_cast<LONG>(radiusX * cos(angle)); points[i].y = ptCenter.y + static_cast<LONG>(radiusY * sin(angle)); } } // 修正后的窗口创建代码 hwnd = CreateWindow( szAppName, "The Windows Program", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 640, // 窗口宽度 480, // 窗口高度 NULL, NULL, hInstance, NULL ); ``` ### 实现WndProc函数示例 ```cpp LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch (msg) { case WM_PAINT: { PAINTSTRUCT ps; HDC hdc = BeginPaint(hwnd, &ps); RECT rc; GetClientRect(hwnd, &rc); POINT points[16]; CalcPoints(points, rc, 16); Polygon(hdc, points, 16); EndPaint(hwnd, &ps); return 0; } case WM_DESTROY: PostQuitMessage(0); return 0; } return DefWindowProc(hwnd, msg, wParam, lParam); } ``` ### 修正说明 1. **内存管理优化** 通过传入预分配数组的方式避免返回局部数组 2. **数学公式修正** 采用正确的极坐标公式: $$ x = x_c + r_x \cdot \cos(\theta) $$ $$ y = y_c + r_y \cdot \sin(\theta) $$ 3. **窗口过程实现** 添加了WM_PAINT消息处理,使用Polygon API绘制正多边形[^1]
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值