日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

[CODEVS 1244] 云中通信

發(fā)布時(shí)間:2025/3/15 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [CODEVS 1244] 云中通信 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

描述

天空中有n朵云,在風(fēng)吹之下以恒定速度v=(vx,vy) 向同一個(gè)方向持續(xù)移動(dòng),也就是說(shuō),當(dāng)時(shí)間為t(t≥0)時(shí),云上初始坐標(biāo)為(x, y)的點(diǎn)移到坐標(biāo)為( x + t*vx, y + t*vy)的位置。

為簡(jiǎn)單起見(jiàn),我們假設(shè)云是多邊形的(而且其頂點(diǎn)具有整數(shù)坐標(biāo))。多邊形不一定是凸的,但是每個(gè)多邊形的任意兩條邊不相交(允許具有公共的端點(diǎn))。云和云可能會(huì)重疊。

地面上有一人造衛(wèi)星控制中心,位于坐標(biāo)(0,0)處,在控制中心正上方的云層之上,有一顆人造衛(wèi)星。一道激光束從控制中心筆直地向上射向人造衛(wèi)星,這道激光束用于與衛(wèi)星進(jìn)行通信。然而,當(dāng)激光束的光路被云遮住時(shí),通信就會(huì)中斷。最初激光束不與任何一片云相交。在觀測(cè)期間,會(huì)有若干個(gè)這樣的時(shí)段,在這些時(shí)段期間激光束的光路穿過(guò)一片或幾片云,使得通信中斷。甚至當(dāng)激光束遇到云的某個(gè)頂點(diǎn)時(shí),通信也會(huì)有瞬間的中斷。你需要寫一個(gè)程序來(lái)計(jì)算在所有云移過(guò)之前,通信會(huì)中斷多少次。

http://codevs.cn/problem/1244/


分析

這個(gè)題題意一直理解的不對(duì), 是只要激光束被擋住就算通信終端還是發(fā)射激光的點(diǎn)被擋住才算通信終端? 看樣例是后者, 但光沿直線傳播的道理是不能被更改的… …

好吧, 實(shí)在不會(huì)寫, 把標(biāo)程注釋翻譯了一遍 (原文是英文注釋), 加了些自己的理解, 也不知道對(duì)不對(duì).

感覺(jué)太高端了, 手寫分?jǐn)?shù)類、手寫62位大整數(shù)乘法… 暈!


代碼

1367ms 19MB


跟原程序比把隨機(jī)調(diào)換交點(diǎn)順序的代碼刪除了, 搞不懂怎么回事, 而且那段代碼風(fēng)格都和其他地方不一樣. 鬧哪樣?

/*************************************************************************} {* *} {* CEOI 2004 *} {* *} {* Sample solution: Clouds *} {* File: CLO.CPP *} {* Author: PIOTR STANCZYK *}*************************************************************************/ #include <cstdio> #include <algorithm> #include <vector> #define MAX_CLOUDS 1000 #define CLOUD_SIZE 1000 #define LOCALtypedef long long int lli; typedef unsigned long long int ulli; const ulli low_part = 2147483647; /* 2^31 - 1 */ // 31 個(gè) 1 const ulli high_part = low_part * (low_part + 2); /* 2^62 - 1 */ // 62 個(gè) 1 using namespace std;struct point {int x,y; };struct superlong {ulli high, low; };struct crossing { /* Intersection point */ // 云和激光的交點(diǎn) lli posh, posl; /* Relative position of the point */ // 在激光上的位置 (比例) short int cloud; /* Owner of the point */ // 所在的云 char type; /* Type of intersection */ // 交點(diǎn)類型 };int vel_x, vel_y, clouds; /* Velocity vector and the number of clouds */ // 移動(dòng)速度正交分解 vector<crossing> cr; /* Vector of intersection points */ // 存激光和云的交點(diǎn) inline superlong multiply(ulli v1, ulli v2) /* Multiplies two unsigned long long ints and returns the result as superlong. ** This function assumes that multiplied values are at most 62-bits long */ // 兩個(gè)無(wú)符號(hào)長(zhǎng)整型 v1,v2 相乘的結(jié)果 {superlong val;ulli x = (v1 & low_part) * (v2 >> 31) + (v1 >> 31) * (v2 & low_part); // x = v1 的后31位乘上 v2 右移31的結(jié)果 + v1 的后31位乘上 v2 右移31的結(jié)果 = ??val.low = (v1 & low_part) * (v2 & low_part);val.high = (v1 >> 31) * (v2 >> 31);val.low += (x & low_part) << 31;val.high += (x >> 31) + (val.low >> 62);val.low = val.low & high_part;return val; }inline int compare(const crossing& a, const crossing& b) /* Compares a position of two given crossing points */ // 先考慮高位再考慮低位判斷大小 {// a : a.posh / a.posl ( > 0 )// b : b.posh / b.posl ( > 0 )// a - b : a.posh*b.posl - a.posl*b.posh / (a.posl*b.posl)// 在正負(fù)符號(hào)上 = a.posh*b.posl - a.posl*b.poshsuperlong a1 = multiply(a.posh, b.posl);superlong b1 = multiply(a.posl, b.posh);if (a1.high == b1.high) {if (a1.low == b1.low) return 0; // a = bif (a1.low < b1.low) return -1; // a < breturn 1; // a > b}if (a1.high < b1.high) return -1;return 1; }inline bool cmp(const crossing& a, const crossing& b) {return (compare(a, b) == -1); // return a < b (比較a, b到激光發(fā)射點(diǎn) (point [0,0]) 的相對(duì)距離大小) }int side(const point& a) /* Determines the location of a given point against velocity vector */ // 計(jì)算給定頂點(diǎn)和速度向量的相對(duì)位置 {lli x = (lli)vel_x * (lli)a.y - (lli)vel_y * (lli)a.x; // 向量 (vel_x, vel_y) 與 向量 (a.x, a.y) 的 叉積if (x == 0) return 0; // 兩個(gè)向量重合 即速度向量過(guò)該點(diǎn) if (x > 0) return 1; // 點(diǎn)在速度向量上方 return -1; // 點(diǎn)在速度向量下方 }void Add_intersection(const point& a, const point& b, short int cloud, char type) /* Examines an intersection point between velocity vector and (a,b) segment */ // 檢查 速度向量 和 線段ab 的交點(diǎn)情況 {crossing c;/* The relative distance of the crossing point from the laser beam (point [0,0]) ** is defined as c.posh/c.posl. In order to keep arithmetic precision we have ** to represent this value as a fraction */// 交點(diǎn)和激光發(fā)射點(diǎn) (point [0,0]) 的相對(duì)距離用 c.posh/c.posl 表示, 采用手寫分?jǐn)?shù)類的方式, 來(lái)避免精度誤差 c.posh = lli (b.y) * lli (a.x) - lli (b.x) * lli (a.y);c.posl = lli (vel_y) * lli (a.x - b.x) - lli (vel_x) * lli (a.y - b.y);if (c.posh < 0 && c.posl < 0) { // 分子分母負(fù)負(fù)得正 c.posh = -c.posh;c.posl = -c.posl;} /* Examined intersection is not important for as */ // 距離為負(fù), 交點(diǎn)在激光的反向延長(zhǎng)線上, 舍掉答案else if (c.posh < 0 || c.posl < 0) return; c.cloud = cloud;c.type = type;cr.push_back(c); }void Read_Data() /* Reads data and finds all intersection points */ // 讀入數(shù)據(jù), 找到所有速度向量與云的交點(diǎn) {int size;point cloud[CLOUD_SIZE]; // 保存云上的頂點(diǎn) scanf("%d %d %d", &clouds, &vel_x, &vel_y);// 運(yùn)用愛(ài)因斯坦狹義相對(duì)論的原理對(duì)速度進(jìn)行等效的處理, 相當(dāng)于云不動(dòng), 坐標(biāo)中心反方向運(yùn)動(dòng) vel_x = -vel_x;vel_y = -vel_y;for(int x = 0; x < clouds; ++x) { // 一共 clouds 朵云 scanf("%d", &size);for(int y = 0; y < size; ++y) {scanf("%d %d", &cloud[y].x, &cloud[y].y);}int pos = 0, f_side, l_side;/* Finds a vertex not located above velocity vector */// 找到一個(gè)不位于速度向量上的頂點(diǎn) 速度向量不過(guò)該點(diǎn) while ( (f_side = side(cloud[pos])) == 0) ++pos; int y = 1;while (y <= size) {l_side = f_side; // l_side 一定不能等于 0 f_side = side(cloud[(pos + y) % size]); // 與當(dāng)前頂點(diǎn)相鄰的下一個(gè)頂點(diǎn)與速度向量的相對(duì)位置 switch (l_side * f_side) {case 1 :/* Vertices are located on the same side -> no intersection */ // 兩頂點(diǎn)位于速度向量的同一側(cè), 連線和速度向量無(wú)交點(diǎn) ++y;break;case -1 : /* Vertices are located on a different sides -> intersection found */ // 兩頂點(diǎn)位于速度向量的不同側(cè), 連線和速度向量有交點(diǎn) Add_intersection(cloud[(pos + y - 1) % size], cloud[(pos + y) % size], x, 0);++y;break;case 0 : /* Vertex is located directly above velocity vector -> further verification */// (pos + y) 位于速度向量上 int beg = pos + y;while ( (f_side = side(cloud[(pos + y) % size])) == 0) ++y;if (pos + y != beg + 1) {// 有很多交點(diǎn), 但只記錄下兩個(gè) Add_intersection(cloud[(pos + y) % size], cloud[(pos + y - 1) % size], x, (l_side == f_side) ? 1 : 2);Add_intersection(cloud[(beg - 1) % size], cloud[beg % size], x, 1);} else { // 只有一個(gè)交點(diǎn) (pos + y), 如果沒(méi)有穿過(guò)激光, type = 3, 否則 type = 0 Add_intersection(cloud[(pos + y - 1) % size], cloud[(pos + y) % size], x, (l_side == f_side) ? 3 : 0);}break;}}} }int Count_Result() /* Searches the sorted list of intersection points and calculates the result */ // 掃描排好序的交點(diǎn)列表, 統(tǒng)計(jì)答案 {bool inside[MAX_CLOUDS]; /* is a cloud directly above the laser beam */ // 激光當(dāng)前是否在該云里面 bool on_edge[MAX_CLOUDS]; /* is an edge of a cloud directly above the laser beam */ // 激光當(dāng)前是否在該云邊緣 int am_edges = 0, am_inside = 0, result = 0;crossing location;location.posh = 0; /* Sets the actual location to the */ // 從初始化的距離為 0 開始掃描 location.posl = 1; /* initial position of the laser beam */ // 分母不是 0 即可 for(int x = 0; x < clouds; ++x)inside[x] = on_edge[x] = false;for(__typeof (cr.begin()) it = cr.begin(); it != cr.end(); ++it) {// 以下三項(xiàng)判斷分別對(duì)應(yīng)著: 當(dāng)前的激光不在云中, 當(dāng)前的激光不在云的邊緣, 當(dāng)前點(diǎn)與上個(gè)點(diǎn)不重合 if (am_inside == 0 && am_edges == 0 && compare(location,*it) != 0) ++result;location = *it;if (location.type == 1 || location.type == 2) /* Intersection changes the state of an edge */ // 交點(diǎn)情況改變邊的狀態(tài) 激光從該云的邊緣上移開 或 激光移動(dòng)到了該云的邊緣上 (on_edge[location.cloud] = !on_edge[location.cloud]) ? ++am_edges : --am_edges;if (location.type == 0 || location.type == 2) /* Intersection changes the state of a cloud */ // 交點(diǎn)情況改變?cè)频臓顟B(tài) 激光從該云中移出 或 激光進(jìn)入該云 (inside[location.cloud] = !inside[location.cloud]) ? ++am_inside : --am_inside;}return result; }int main() {Read_Data();// 把交點(diǎn)按照距離激光發(fā)射點(diǎn) (point [0,0]) 的相對(duì)距離從近到遠(yuǎn)排序 sort(cr.begin(), cr.end(), cmp);printf("%d\n", Count_Result());return 0; }

總結(jié)

以上是生活随笔為你收集整理的[CODEVS 1244] 云中通信的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。