1. 程式人生 > 其它 >CSP 2020-09解答

CSP 2020-09解答

技術標籤:cspc++

CSP 2020-09

2020-09-1 稱監測點查詢

#include<iostream>
#include<math.h>
#include<algorithm>
using namespace std;
//n,X,Y表示檢測點數和市民所在位置
int n, x, y;
int checkx[202];	//儲存檢測點的位置
int checky[202];
struct distant {
	int dis;	//距離
	int order;	//序號
}dist[202];
//輸出距離該市民最近的三個點的編號,從1開始
bool cmp(const
distant a, const distant b) { if (a.dis == b.dis) return a.order < b.order; //!!! return a.dis < b.dis; } int main(void) { cin >> n >> x >> y; int i; for (i = 0; i < n; i++) cin >> checkx[i] >> checky[i]; for (i = 0; i < n; i++) { dist[i].dis = pow
(abs(x - checkx[i]), 2) + pow(abs(y - checky[i]), 2);//可以不開根 dist[i].order = i + 1; } sort(dist, dist + n,cmp); for (i = 0; i < 2; i++) cout << dist[i].order << endl; cout << dist[2].order; return 0; }

2020-09-2 風險人群篩查

這裡我出現多次超時。我認為我的寫法的時間複雜度時O(n²),因為使用了兩層for迴圈。檢查結果為40分出現超時的情況。但是我看了網上的程式碼,估計其時間複雜度也為O(n²),畢竟如果要一次性讀入全部的資料,肯定需要平方的時間。

後來仔細對比網上的程式碼,出現超時的原因應該是我分配空間太大導致耗時較大。我之前定義了兩個結構體,一個是位置結構體,表示座標,一個結構體用於表示一個人的所有座標。如下:

struct coordinate {
	int x;
	int y;
};
struct position {
	//表示一個居民的在t個時刻的位置
	struct coordinate pos[1002];
}people[21];

這是全域性的變數,定義數量為21和1002是因為要求座標數≤1000,人數≤20。

這樣寫出來的程式碼執行一遍的空間花銷達到了12MB,且超時,而網上別人的程式碼一般是2,3MB左右,時間為30ms左右。
在這裡插入圖片描述在這裡插入圖片描述

所以修改為只定義座標結構體,在第一層for迴圈內(遍歷人數),第二層for迴圈外(遍歷每一個人的座標),分配strcut coordinate pos[1002]。

修改後成功AC。
程式碼如下:

#define _CRT_SECURE_NO_WARNINGS
#include<string>
#include<stdio.h>
int n, k, t;
struct coordinate {
	int x;
	int y;
};
int xl, yd, xr, yu;
int main(void) {
	scanf("%d%d%d%d%d%d%d",&n,&k,&t,&xl, &yd, &xr,&yu);
	//連續!!!>=k個座標位於區間內為逗留
	//有一個在就是經過
	int count = 0, count_in = 0, count_danger = 0;
	int i,j,flag,flag1;
	for (i = 0; i < n; i++) {
		count = 0;
		flag = 0;
		flag1 = 1;
		struct coordinate pos[1002];
		for (j = 0; j < t; j++) {
			scanf("%d%d", &pos[j].x, &pos[j].y);
			if (pos[j].x >= xl && pos[j].y >= yd && pos[j].x <= xr && pos[j].y <= yu) {
				count++;
				flag = 1;
				if (count >= k && flag1) {
					count_danger++;	//高危
					flag1 = 0;
				}
			}
			else
				count = 0;
		}
		if (flag)
			count_in++;	//經過
	}
	printf("%d\n%d\n", count_in, count_danger);
}

使用scanf和prinf是因為當資料量比較大時,它們會比cin和cout省時,但顯然這裡的問題並不在與輸入輸出的耗時。