【原创】2019.08.15 模拟赛 ※ [USACO19]Left Out / [USACO19]Cow Steeplechase II / bzoj 4972 小Q的方格纸
Index
- 2019.08.15
- 說在前面
- 變換隊形
- 【問題描述】
- 【輸入格式】
- 【輸出格式】
- 【輸入輸出樣例 】
- 【輸入輸出樣例說明】
- [USACO19OPEN]Left Out
- 題目描述
- 輸入格式
- 輸出格式
- 輸入輸出樣例
- 輸入
- 輸出
- 說明/提示
- 分析
- 代碼
- 跨欄
- 【問題描述】
- 【輸入格式】
- 【輸出格式】
- 【輸入輸出樣例】
- jump.in
- jump.out
- 提示
- [USACO19]Cow Steeplechase II
- 題目描述
- 輸入格式
- 輸出格式
- 輸入輸出樣例
- 輸入 #1
- 輸出 #1
- 說明/提示
- 分析
- bzoj 4972 [Lydsy1708月賽] 小Q的方格紙
- Description
- Input
- Output
- Sample Input
- Sample Output
- 題意分析
- 代碼
2019.08.15
說在前面
寫博客咯
還剩85天。
變換隊形
(transitioning.cpp/c/pas)
【問題描述】
有一個調皮的班級,他們上體育課,現在排成了n行n列的一個矩形。每個人卻不是面向老師,而是面向左側或右側。例如:
RLR
RRL
LLR
因為老師是新來的,所以還叫不出學生的名字。他每次都是朝著一列或一行喊:向后轉。這一行或這一列的L就全部變成R,R就全部變成L。因為不能讓所有學生都朝一個方向,所以體育老師退而求其次,他可以允許一個人和其他人方向相反。體育老師的指令沒有次數限制,他也可以對同一行或同一列進行多次發令。請找出這樣的一個學生。如果最后無法使得只有一個學生和其他人方向相反,則輸出“-1”。如果存在方案,則輸出那一個學生的行號和列號(均從1開始)。如果有多種方案,則輸出行號最小的那一個學生,如果多個學生的行坐標相等,則輸出列號最小的那一個。
【輸入格式】
輸入文件名為 transitioning.in。
第一行一個整數,表示n。
接下來是n行,每行n個字符,每一個字符為L或R。
【輸出格式】
輸出文件名為 transitioning.out。
輸出文件只有 1 行,表示那個討厭的學生的行號和列號。
如果沒有,則輸出-1。
【輸入輸出樣例 】
| RLRRRLLLR\begin{array}{lcrlcr} RLR \\ RRL \\ LLR \end{array}RLRRRLLLR? | 111~~~11???1 |
【輸入輸出樣例說明】
在這個例子中,位于第1行第1列(左上角)的學生是那個令人討厭的學生,因為老師可以喊叫第2行和第3列向后轉,只有這一個學生和其他學生朝向不同。
以上是魔改后題面,以下是原題面。
[USACO19OPEN]Left Out
題目描述
Farmer John正在嘗試給他的牛群拍照。根據以往的經驗,他知道這一工作往往結果不怎么樣。
這一次,Farmer John購買了一臺昂貴的無人機,想要拍一張航拍照。為了使照片盡可能好看,他想讓他的奶牛們在拍照時都朝向同一個方向。奶牛們現在在一塊有圍欄的草地上排列成 N \times N N×N ( 2 \leq N \leq 1000 2≤N≤1000 )的方陣,例如:
RLR
RRL
LLR
這里,字符’R’表示一頭朝右的奶牛,字符’L’表示一頭朝左的奶牛。由于奶牛們都擠在一起,Farmer John沒辦法走到某一頭奶牛面前讓她調轉方向。他能做的只有對著某一行或某一列的奶牛喊叫讓她們調轉方向,使得被叫到的這一行或列內的所有L變為R,R變為L。Farmer John可以對任意多的行或列發號施令,也可以對同一行或列多次發令。
就如同Farmer John想象的,他發現他不可能讓他的奶牛們都朝向同一個方向。他最多能做的是讓所有奶牛中除了一頭之外都朝向相同的方向。請找出這樣的一頭奶牛。
輸入格式
輸入的第一行包含 N N 。以下 N N 行描述了奶牛方陣的第 1 \ldots N 1…N 行,每行包含一個長度為 N N 的字符串。
輸出格式
輸出一頭奶牛的行列坐標,滿足這頭奶牛被調轉方向的話,Farmer John就可以使他的所有奶牛都朝向同一個方向。如果不存在這樣的奶牛,輸出-1。如果存在多頭這樣的奶牛,輸出其中行坐標最小的,如果多頭這樣的奶牛具有相同的行坐標,輸出其中列坐標最小的。
輸入輸出樣例
輸入
3
RLR
RRL
LLR
輸出
1 1
說明/提示
在這個例子中,位于第1行第1列(左上角)的奶牛是那頭令人討厭的奶牛,因為Farmer John可以喊叫第2行和第3列來讓所有奶牛都面向左側,只有這一頭奶牛面向右側。
分析
可以把題意抽象為如下:有n*n的01矩陣,每次操作可以將一行或一列的所有元素取反,問經過若干次操作之后,是否能使矩陣只有一個1或只有一個0,若能,則輸出這個數字的坐標,反之輸出-1。
銀組第一題,普及+/提高題。
我沒有做出來。
考試的題解是如下說的,如圖,用顏色代表0和1。
假設我們要讓最后一排的顏色統一。
首先我們用豎排的變化讓最后一排都變為橙色,那么之后我們就不能再變化豎排了,這樣的話最后一排的統一就會被破壞,所以打叉的那兩個(只依靠橫排變化)是不可能與這一排的其他人統一的,因此就會違法“只有一個人和大家方向不同”,因此impossible。
如果我們想統一的不是最后一排,同理。
其實本質相同,只是讓最后一排統一,就可以保證要求的那個人不在最后一排,答案稍稍更優。
當然,這只是我們思考的一步,我們邁出了一步再來看能不能達到期望的結局,然后在退一步回來推理怎樣的原圖能到達期望的結局。
注意,我們已經統一了最后一排,所以不進行豎變化。
那么只靠橫變化能夠將怎樣的圖變為目標圖呢?
答案是比較顯然的,就是有且僅有一個橫排其中較少的數量為1個,其余的橫排都是相同的。
也就是說:
①不能全都是同色橫排;
②不能有一個橫排,異色的格子有兩個或兩個以上;(異色指較少數量的格子)
③必須有一個橫排其中有一個異色格子;
④不能有兩個或兩個以上個橫排其中有一個異色格子。
所以說我們在把最后一行統一以后,枚舉剩下的橫排,數它們其中的異色塊數
還有一種情況,是我一開始隨手畫圖畫出來的,是上述方法不能解決的。
為什么隨手畫會畫出特例啊啊啊
上面那個引用塊說“這樣就可以保證答案不在最后一排”。
這就是這個算法的漏洞。
我隨手畫的圖把std爆破了。
就是答案在最后一排的情況。
這樣的話,統一了最后一排就錯了;
不過這樣的話答案的上方全都是單個的異色塊,也很好特判。
代碼
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std;const int MAXN=1024; char mp[MAXN]; int n,R,ansx,ansy,cnt,is[MAXN][MAXN];int main() {scanf("%d",&n);if(n==1) return puts("1 1"),0;for(int i=1;i<=n;i++){scanf("%s",mp+1);for(int j=1;j<=n;j++) is[i][j]=mp[j]=='R';}for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)if(is[n][j]) is[i][j]^=1;for(int i=1;i<=n && cnt<=n;i++){R=0;for(int j=1;j<=n;j++) R+=is[i][j];if(R!=0 && R!=n && R!=1 && R!=n-1) {cnt=2147484647; break;} if(R==1 || R==n-1){cnt++;for(int j=1;j<=n;j++)if(is[i][j]==(R==1)) {if(cnt>1) {if(ansy!=j) cnt=2147483647;}else ansx=i,ansy=j;break;}}}if(cnt==1 || cnt==n-1) printf("%d %d\n",cnt==n-1?n:ansx,ansy); else puts("-1");return 0; }跨欄
(jump.cpp/c/pas)
【問題描述】
在過去,校長曾經構思了許多新式學生運動項目的點子,其中就包括學生障礙賽,是學生們在賽道上跑越障礙欄架的競速項目。他之前對推廣這項運動做出的努力結果喜憂參半,所以他希望在他的操場上建造一個更大的學生障礙賽的場地,試著讓這項運動更加普及。校長為新場地精心設計了N個障礙欄架,編號為1…N(2≤N≤10510^5105),每一個欄架都可以用這一場地的二維地圖中的一條線段來表示。這些線段本應兩兩不相交,包括端點位置。
不幸的是,校長在繪制場地地圖的時候不夠仔細,現在發現線段之間出現了交點。然而,他同時注意到只要移除一條線段,這張地圖就可以恢復到預期沒有相交線段的狀態(包括端點位置)。
請求出校長為了恢復沒有線段相交這一屬性所需要從他的計劃中刪去的一條線段。如果有多條線段移除后均可滿足條件,請輸出在輸入中出現最早的線段的序號。
【輸入格式】
輸入的第一行包含N。余下N行每行用四個整數x1 y1 x2 y2表示一條線段,均為至多10910^9109的非負整數。這條線段的端點為(x1,y1)和(x2,y2)。所有線段的端點各不相同。
【輸出格式】
輸出在輸入中出現最早的移除之后可以使得余下線段各不相交的線段序號。
【輸入輸出樣例】
jump.in
4
2 1 6 1
4 0 1 5
5 6 5 5
2 7 1 3
jump.out
2
提示
注意:由于線段端點坐標數值的大小,在這個問題中你可能需要考慮整數類型溢出的情況
以上是魔改題面,以下是原題面:
[USACO19]Cow Steeplechase II
題目描述
在過去,Farmer John曾經構思了許多新式奶牛運動項目的點子,其中就包括奶牛障礙賽,是奶牛們在賽道上跑越障礙欄架的競速項目。他之前對推廣這項運動做出的努力結果喜憂參半,所以他希望在他的農場上建造一個更大的奶牛障礙賽的場地,試著讓這項運動更加普及。
Farmer John為新場地精心設計了N個障礙欄架,編號為 1…N(2≤N≤105)1 \ldots N(2 \leq N \leq 10^5)1…N(2≤N≤105),每一個欄架都可以用這一場地的二維地圖中的一條線段來表示。這些線段本應兩兩不相交,包括端點位置。
不幸的是,Farmer John在繪制場地地圖的時候不夠仔細,現在發現線段之間出現了交點。然而,他同時注意到只要移除一條線段,這張地圖就可以恢復到預期沒有相交線段的狀態(包括端點位置)。
請求出Farmer John為了恢復沒有線段相交這一屬性所需要從他的計劃中刪去的一條線段。如果有多條線段移除后均可滿足條件,請輸出在輸入中出現最早的線段的序號。
輸入格式
輸入的第一行包含 N 。余下 N 行每行用四個整數x1,y1,x2,y2x_1,y_1,x_2,y_2x1?,y1?,x2?,y2?表示一條線段,均為至多10910^9109的非負整數。這條線段的端點為(x1,y1)(x_1,y_1)(x1?,y1?) 和(x2,y2)(x_2,y_2)(x2?,y2?)) 。所有線段的端點各不相同。
輸出格式
輸出在輸入中出現最早的移除之后可以使得余下線段各不相交的線段序號。
輸入輸出樣例
輸入 #1
4
2 1 6 1
4 0 1 5
5 6 5 5
2 7 1 3
輸出 #1
2
說明/提示
注意:由于線段端點坐標數值的大小,在這個問題中你可能需要考慮整數類型溢出的情況。
分析
首先,既然題目保證刪掉某一條邊之后,剩下的邊都不相交,那么就一定有如下性質:
如果有兩條線段相交,那么答案一定是其中之一。\Large \bold 如果有兩條線段相交,那么答案一定是其中之一。如果有兩條線段相交,那么答案一定是其中之一。
我居然忽略了這么顯然的性質。
于是就可以Θ(n2)\Theta(n^2)Θ(n2)枚舉點對了。
然后考慮優化。
把所有端點按照從左到右從下到上排序,
以下內容博主咕掉了,詳情請參見https://blog.csdn.net/c20180602_csq/article/details/99655074這篇大佬的博客。
bzoj 4972 [Lydsy1708月賽] 小Q的方格紙
Time Limit: 10 Sec Memory Limit: 256 MB
Description
方格紙與草稿紙一樣,都是算法競賽中不可或缺的重要工具。身經百戰的小Q自然也會隨身帶著方格紙。小Q的方格紙有nnn行m列,一共n?mn*mn?m個方格,從上到下依次標記為第1,2,...,n1,2,...,n1,2,...,n行,從左到右依次標記為第1,2,...,m1,2,...,m1,2,...,m列,方便起見,小Q稱第i行第j列的方格為(i,j)(i,j)(i,j)。小Q在方格紙中填滿了數字,每個格子中都恰好有一個整數ai,ja_{i,j}ai,j?。小Q不喜歡手算,因此每當他不想計算時,他就會讓你幫忙計算。小Q一共會給出q個詢問,每次給定一個方格(x,y)(x,y)(x,y)和一個整數k(1<=k<=min(x,y))k(1<=k<=min(x,y))k(1<=k<=min(x,y)),你需要回答由(x,y),(x?k+1,y),(x,y?k+1)(x,y),(x-k+1,y),(x,y-k+1)(x,y),(x?k+1,y),(x,y?k+1)三個格子構成的三角形邊上以及內部的所有格子的a的和。
Input
第一行包含6個正整數n,m,q,A,B,C(1<=n,m<=3000,1<=q<=3000000,1<=A,B,C<=1000000)n,m,q,A,B,C(1<=n,m<=3000,1<=q<=3000000,1<=A,B,C<=1000000)n,m,q,A,B,C(1<=n,m<=3000,1<=q<=3000000,1<=A,B,C<=1000000)
其中n,mn,mn,m表示方格紙的尺寸,q表示詢問個數。
為了防止輸入數據過大,a和詢問將由以下代碼生成:
Output
為了防止輸出數據過大,設fif_ifi?表示第iii個詢問的答案,則你需要輸出一行一個整數,即:
(∑i=1q233q?i?fi)mod232(\sum_{i=1}^q 233^{q-i}*f_i) mod~2^{32}(∑i=1q?233q?i?fi?)mod?232
Sample Input
3 4 5 2 3 7
Sample Output
3350931807
本題沒有被魔改。
題意分析
有一個n*m的方格,每次給定一個x,y,k,求(x,y),(x?k+1,y),(x,y?k+1)(x,y),(x-k+1,y),(x,y-k+1)(x,y),(x?k+1,y),(x,y?k+1)三個格子構成的三角形的所占格子的和。
首先如上圖,我們把這個格子三角形簡化為線段的三角形。
我們假設我們要求那個紅色邊框三角形的和,也就是下圖的橙色三角形。
那么如易知,橙色=紅色長方形-藍色長方形-綠色梯形=紅色長方形-藍色長方形-(粉色三角形-紫色三角形)。
紅色和藍色長方形非常容易用前綴和預處理出來,之后粉色和紫色的三角形是同一類的stand……shape呢,也可以輕松地預處理出來。
粉色三角=紅色三角+橙色長方=紅色三角+(紫色長方-綠色長方)
這道題就輕松的做了出來。
(但是看我畫的圖就非常不輕松,博主藝術天分為-2147483647,上色r智,請見諒,將就看就好了)
代碼
#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>using namespace std;const int MAXN=3030;int n,m,q,x,y,k;unsigned int A,B,C,t,a[MAXN][MAXN],sum[MAXN][MAXN],sig[MAXN][MAXN],ret,ans;inline unsigned rng61(){A^=A<<16,A^=A>>5,A^=A<<1;t=A,A=B,B=C,C^=t^A;return C;}int main(){scanf("%d %d %d %u %u %u",&n,&m,&q,&A,&B,&C);for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) a[i][j]=rng61();for(int i=1;i<=max(n,m);i++)for(int j=1;j<=max(n,m);j++)sum[i][j]=sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1]+a[i][j];for(int i=1;i<=max(n,m);i++)for(int j=max(n,m);j>=1;j--)sig[i][j]=sig[i-1][j+1]+sum[j][i]-sum[j-1][i];while(q--){x=rng61()%n+1,y=rng61()%m+1,k=rng61()%min(x,y)+1;ret=(sum[x][y]-sum[x-k][y])-(sig[y-1][x-k+1]-sig[y>k?y-k-1:0][x+1]);ans=ans*233+ret;}printf("%u\n",ans);return 0;}總結
以上是生活随笔為你收集整理的【原创】2019.08.15 模拟赛 ※ [USACO19]Left Out / [USACO19]Cow Steeplechase II / bzoj 4972 小Q的方格纸的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 最难忘的一节计算机课,作文:最难忘的一节
- 下一篇: HTML实现舔狗日记