【codeforces】【比賽題解】#849 CF Round #431 (Div.2)

cf的比賽越來越有難度了……至少我做起來是這樣。

先看看題目吧:點我。

這次比賽是北京時間21:35開始的,算是比較良心。

【A】奇數與結束

"奇數從哪里開始,又在哪里結束?夢想從何處起航,它們又是否會破滅呢?"

給定一個長度為n的序列。確定能不能將序列分成奇數個長度為奇數的非空字串,而且這其中每個子串以奇數開頭,以奇數結尾。可以只分成一個(1也是奇數)。

輸入

第一行一個正整數n,表示序列長度。

第二行n個整數,表示序列中的元素。

輸出

輸出"Yes"或"No"來表示能否做到把序列按要求分割。

樣例輸入1

5
1 0 1 5 1

樣例輸出1

Yes

樣例輸入2

4
3 9 9 3

樣例輸出2

No

題解

當時想了一個n2的DP,之后發現實在是太naive。

講一下DP思路吧,用f1[i]表示能否將a[1...i]分割成奇數個奇數長度的子串,并且每個子串以奇數開頭結尾,f2[i]表示能否分割成偶數個子串。

于是f1[i]=OR(f2[j] (a[j+1...i]長度為奇數并且以奇數開頭結尾) ),f2[i]=OR(f1[j] (a[j+1...i]長度為奇數并且以奇數開頭結尾) ).

特別的,f1[0]=false,f2[0]=true。

這種做法就可以過了,但是有更優秀的做法:

把序列分成奇數個奇數長度的序列,那么這個序列也是奇數長度的。偶數長度的直接No。

再考慮把序列分成兩個以上的序列,那么最開始的序列的起始元素必須是奇數,最末尾的序列的結尾元素也必須是奇數。

這就對應了原序列的第一個與最后一個元素必須是奇數,而這時我們只分一段就好了。

就是說我們只需要判斷n的奇偶,a[1]的奇偶和a[n]的奇偶就可以了。

程序:

 1 #include <cstdio>
 2 static const int MAXN = 102;
 3 
 4 int n;
 5 int a[MAXN];
 6 
 7 int main()
 8 {
 9     scanf("%d", &n);
10     for (int i = 0; i < n; ++i) scanf("%d", &a[i]);
11 
12     puts((n & 1) && (a[0] & 1) && (a[n - 1] & 1) ? "Yes" : "No");
13     return 0;
14 }

【B】

目前沒做出來,調出來了再說自己的做法吧

先貼標程:

 1 #include <bits/stdc++.h>
 2 #define eps 1e-7
 3 using namespace std;
 4 int read()
 5 {
 6     int x=0,f=1;char ch=getchar();
 7     while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
 8     while (ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
 9     return x*f;
10 }
11 int n,a[1007];
12 bool vis[1007];
13 bool check(double k,int b)
14 {
15     memset(vis,false,sizeof(vis));
16     int cnt=0;
17     for (int i=1;i<=n;i++)
18     {
19         if (a[i]-b==1LL*k*(i-1)) 
20         {
21             vis[i]=true;
22             ++cnt;
23         }
24     }
25     if (cnt==n) return false;
26     if (cnt==n-1) return true;
27     int pos1=0;
28     for (int i=1;i<=n;i++)
29         if (!vis[i]&&pos1==0) pos1=i;
30     for (int i=pos1+1;i<=n;i++)
31         if (!vis[i])
32         {
33             if (fabs((double)(a[i]-a[pos1])/(i-pos1)-k)>eps) return false;
34         }
35     return true;
36 }
37 int main()
38 {
39     n=read();
40     for (int i=1;i<=n;i++)
41         a[i]=read();
42     bool ans=false;
43     ans|=check(1.0*(a[2]-a[1]),a[1]);
44     ans|=check(0.5*(a[3]-a[1]),a[1]);
45     ans|=check(1.0*(a[3]-a[2]),a[2]*2-a[3]);
46     if (ans) printf("Yes\n"); else printf("No\n");
47     return 0;
48 }

【C】

題目都沒看懂,真的很難受,這題挺難的。

標程:

 1 #include <bits/stdc++.h>
 2 
 3 using namespace std;
 4 
 5 using ll = long long;
 6 using ld = long double;
 7 using D = double;
 8 using uint = unsigned int;
 9 template<typename T>
10 using pair2 = pair<T, T>;
11 
12 #ifdef WIN32
13     #define LLD "%I64d"
14 #else
15     #define LLD "%lld"
16 #endif
17 
18 #define pb push_back
19 #define mp make_pair
20 #define all(x) (x).begin(),(x).end()
21 #define fi first
22 #define se second
23 
24 int main()
25 {
26     int k;
27     scanf("%d", &k);
28     for (int i = 0; i < 26; i++)
29     {
30         int cnt = 1;
31         while ((cnt + 1) * cnt / 2 <= k) cnt++;
32         k -= cnt * (cnt - 1) / 2;
33         for (int j = 0; j < cnt; j++) printf("%c", 'a' + i);
34     }
35     return 0;
36 }

【D】Rooter's Song

"無論目標何在,無論遇見何人,讓我們一同將這首歌傳唱。"

在平面直角坐標系中,有一個長方形舞臺,四角分別是(0,0),(0,h),(w,0),(w,h)。

可以看出在有任何人進入舞臺之前,不會有任何碰撞發生。

在舞臺的左邊界和下邊界站著一些舞者。分成兩組:

①豎直:站在(xi,0)上,沿著y正方向前進(向上)。

②水平:站在(0,yi)上,沿著x正方向前進(向右)。

按照編舞指導,第i個舞者需要在前ti毫秒內站著不動,然后沿著指定方向以1單位/毫秒的速度前進,直到碰到舞臺的邊界為止。

當兩個舞者碰撞時,她們會立刻改變各自的前進方向,然后繼續沿著新的方向前進。

舞者們只要碰到了舞臺的邊界就會停止,請求出每個舞者最終停下的位置。

輸入

第一行有三個數n,w,h。表示舞者數量,舞臺的長寬。

接下來n行,每行三個數,gi,pi,ti,表示第i個舞者所在的組(gi=1:豎直組;gi=2:水平組),坐標位置(gi=1則pi=xi;gi=2則pi=yi)以及等待時間。

保證0<xi<w,0<yi<h。并保證沒有兩個舞者既在相同的組,還有相同的位置和等待時間。

輸出

n行,每行兩個數xi,yi。表示第i個舞者最終停在哪里。

樣例輸入1

8 10 8
1 1 10
1 4 13
1 7 1
1 8 2
2 2 0
2 5 14
2 6 0
2 6 1

樣例輸出1

4 8
10 5
8 8
10 6
10 2
1 8
7 8
10 6

樣例輸入2

3 2 3
1 1 2
2 1 1
1 1 5

樣例輸出2

1 3
2 1
1 3

數據范圍及提示

1<=n<=100000,2<=w,h<=100000,1<=gi<=2,1<=pi<=99999,0<=ti<=100000。

對于樣例數據1,這是對應的圖:

對于樣例數據2,沒有舞者碰撞。

題解

很難的一題,不過我看來比C題簡單……

注意到每個舞者出發后,每毫秒其坐標總是有一個加一,故(xi+yi)總是在增加。

而且我們發現,只有(xi+yi)相同的舞者才會碰撞。我們把(xi+yi)的值相同的舞者分在一起處理。

如何確定(xi+yi)的值呢??可以發現對于每個舞者,可以把(pi-ti)近似看做(xi+yi),(pi-ti)相同的舞者可能碰撞,而(pi-ti)不同的不可能碰撞。

我們對舞者按照(pi-ti)排序,處理出(pi-ti)相同的舞者。

對于(pi-ti)相同的舞者,我們如何處理呢?

試著把舞臺斜過來看吧!讓(0,0)在最下方,(w,h)在最頂端,(0,h)在左側,(w,0)在最右側。

這樣,對于那些(pi-ti)相同的舞者,即出發后(xi+yi)相同的舞者們,她們在同一時間點必然處在同一水平線上。

并且每過一毫秒,她們向上走√2/2單位,向左或向右走√2/2單位。

這時候的碰撞要如何處理呢?

注意到在沒有碰撞發生前,舞者從左到右的順序是先是水平方向的舞者,坐標從大到小下來,然后是豎直方向的舞者,坐標從小到大往右走。

而所有碰撞都發生了之后呢??舞者的相對位置是不會改變的!原本在最左側的舞者,仍然在左側。舞者位置不會交換。

或者……這是另一種形式的交換了呢?注意到在水平方向坐標最大的舞者沒有去到她本來應該去的位置,而是去了豎直方向第一個舞者應該去的位置。

是的,她們的位置交換了,但是這種交換很有規律,把舞者分成水平方向和豎直方向,那么水平方向的舞者按順序要去到豎直方向的舞者按順序應該去到的位置。依次推下來,就可以確定舞者最終的位置。我不太好解釋這種方法的具體實現,先貼代碼吧。

排序時要注意第一關鍵字是(pi-ti),第二關鍵字是先水平,后豎直,第三關鍵字是初始坐標,水平的從大到小,豎直的從小到大。

復雜度O(nlogn)

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cstring>
 4 #define F(i,a,b) for(int i=a;i<=b;++i)
 5 #define F2(i,a,b) for(int i=a;i<b;++i)
 6 int n,w,h,g[100002],p[100002],t[100002],I[100002],Ans[100002],Ansg[100002];
 7 inline bool cmp(int x,int y){
 8     if(p[x]-t[x]<p[y]-t[y]) return 1;
 9     else if(p[x]-t[x]>p[y]-t[y]) return 0;
10     else{
11         if(g[x]>g[y]) return 1;
12         else if(g[x]<g[y]) return 0;
13         else{
14             if(g[x]==1) return p[x]<p[y];
15             else return p[x]>p[y];
16         }
17     }
18 }
19 int main(){
20     scanf("%d%d%d",&n,&w,&h);
21     F(i,1,n) scanf("%d%d%d",g+i,p+i,t+i),I[i]=i;
22     std::sort(I+1,I+n+1,cmp);
23     I[n+1]=0; p[0]=99999999; t[0]=-99999999;
24     int hor=0,ver=0;
25     F(i,1,n){
26         if(g[I[i]]==1) ++ver; else ++hor;
27         if(p[I[i]]-t[I[i]]!=p[I[i+1]]-t[I[i+1]]){
28             int j=i-hor-ver+1, k=i-ver+1,l,o;
29             for(l=k,o=j;l<=i;++l,++o)
30                 Ans[I[o]]=p[I[l]],Ansg[I[o]]=g[I[l]];
31             for(;o<=i;++o,++j)
32                 Ans[I[o]]=p[I[j]],Ansg[I[o]]=g[I[j]];
33             ver=hor=0;
34         }
35     }
36     F(i,1,n) if(Ansg[i]==1) printf("%d %d\n",Ans[i],h); else printf("%d %d\n",w,Ans[i]);
37     return 0;
38 }

【E】

沒看題,以后再補吧。

轉載于:https://www.cnblogs.com/PinkRabbit/p/7466204.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/251923.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/251923.shtml
英文地址,請注明出處:http://en.pswp.cn/news/251923.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

PaddleDetection支持的數據格式

PaddleDetection支持的數據格式 目前#PaddleDetection支持43種數據格式&#xff1a;coco voc widerface。在這里我們主要說明一下如何使用自定義COCO進行目標檢測、實例分割&#xff1b;如何使用自定義VOC數據集進行目標檢測。在PaddleDetection新的版本中&#xff0c;我們將數…

[dts]Device Tree機制【轉】

轉自&#xff1a;https://www.cnblogs.com/aaronLinux/p/5496559.html 轉自&#xff1a;http://blog.csdn.net/machiner1/article/details/47805069 ------------------Based on linux 3.10.24 source code 參考/documentation/devicetree/Booting-without-of.txt文檔 目錄 1.…

AntiSamy測試

AntiSamy為owasp針對xss提供的處理庫&#xff0c;可以配置xml策略來決定過濾的內容&#xff0c;比如標簽、屬性、css等&#xff0c;自定義策略給開發人員使用成本比較高&#xff0c;AntiSamy也提供了幾個內置的策略&#xff0c;其安全級別也不同&#xff0c;過濾的內容也不一樣…

1625 數字金字塔

1625 數字金字塔 鏈接&#xff1a;http://codevs.cn/problem/1625/ USACO 時間限制: 1 s空間限制: 128000 KB題目描述 Description考慮在下面被顯示的數字金字塔. 寫一個程序來計算從最高點開始在底部任意處結束的路徑經過數字的和的最大. 每一步可以走到下方的點也可以到達右…

ubuntu下的能安裝的百度網盤的資源最新網址

Index of /deepin/pool/non-free/d/deepin.com.baidu.pan/

C# 匿名委托、匿名方法、匿名對象、Lambda表達式

C# 匿名委托、匿名方法、匿名對象、Lambda表達式 原文:C# 匿名委托、匿名方法、匿名對象、Lambda表達式一、匿名類型可通過使用 new 運算符和對象初始值創建匿名類型。示例&#xff1a;var v new { Name "Micro", Message "Hello" };var v new[] { …

【9018:1956】線段樹1

問題 D: 【模板】線段樹1 時間限制: 1 Sec 內存限制: 512 MB提交: 80 解決: 40[提交][狀態][討論版]題目描述 給定一個無序數列&#xff0c;有四種操作&#xff1a; 1.令數列中的某個數加上某個數 2.求一個區間的和 3.查詢一段區間內的最大值&#xff1b; 4.查詢一段區間內的…

c++調用函數的dll

在工程項目中&#xff0c;為了不暴露源代碼和避免嚴重耦合&#xff0c;所以將代碼封裝成 .dll二進制文件&#xff0c;以供項目調用。 這幾天&#xff0c;也是在看這些封裝dll&#xff0c;并使用Java中的JNA調用c的dll鏈接庫中的函數&#xff0c;做個筆記&#xff01; 1、創建…

SoJpt Boot 2.2-3.8 發布,Spring Boot 使用 Jfinal 特性極速開發

開發四年只會寫業務代碼&#xff0c;分布式高并發都不會還做程序員&#xff1f; 在Spring Boot框架下使用Jfinal特性極速開發,可以在Spring Boot中向使用Jfinal一樣使用Enjoy、Aop、Controller等一系列方法(如: getFile(), renderFile....),以及ActiveRecord SoJpt Boot&…

組合數學--約瑟夫環問題 Josephus

約瑟夫斯問題&#xff08;有時也稱為約瑟夫斯置換&#xff09;&#xff0c;是一個出現在計算機科學和數學中的問題。在計算機編程的算法中&#xff0c;類似問題又稱為約瑟夫環。 有n個囚犯站成一個圓圈&#xff0c;準備處決。首先從一個人開始&#xff0c;越過k-2個人&#xff…

3軸機器人各關節運動學建立,python編程,非常容易理解

分類&#xff1a;機器人學 一、問題描述 如右圖所示的三自由度機械臂&#xff0c;關節1和關節2相互垂直&#xff0c;關節2和關節3相互平行。如圖所示&#xff0c;所有關節均處于初始狀態。 要求: (1) 定義并標注出各關節的正方向&#xff1b; (2) 定義機器人基坐標系&#x…

ASP.Net中頁面傳值的幾種方式

大致概括一下&#xff0c;ASP.NET 頁面之間傳遞值得方式大致可以分為如下幾種&#xff1a;Request.QueryString["name"],Request.Form("name"),Session,Cookie,Cache,Application,Server.Transfer,Database,HttpContext的Item屬性&#xff0c;Files,DataBa…

Win 10 源碼一覽:0.5T 代碼、400 萬文件、50 萬文件夾

Windows 操作系統本身是不開源的&#xff0c;但是近日微軟內核工程師 Axel Rietschin 發表了一篇博客&#xff0c;帶大家一窺了 Windows 10 內核的魅力。 Axel 介紹&#xff0c;Windows 10 與 Windows 8.x、7、Vista、XP、2000 和 NT 的代碼庫是相同的&#xff0c;其中每一代都…

老齊python-基礎3(列表)

1、定義一個列表 >>> a [] #創建一個空列表 >>> type(a) #查看數據類型 <class list> >>> bool(a) #判斷非空 False >>> print(a) [] >>> a [2,3,tajzhang,] >>> a [2, 3, tajzhang] >&…

UWP 響應鍵盤組合快捷鍵

方法1&#xff1a;響應Ctrl&#xff1f;快捷鍵 首先在load事件或者keydown事件內注冊事件 public MainPage(){this.InitializeComponent();// Register for accelerator key events used for button hotkeysWindow.Current.CoreWindow.Dispatcher.AcceleratorKeyActivated Dis…

NDK 開發實戰 - 封裝 java 層 sdk 模型

關于 Ndk 開發&#xff0c;網上的資料比較少&#xff0c;這方面的書籍也不多。因為其涉及的知識非常廣&#xff0c;時常有哥們問我&#xff0c;東西那么多到底要學到什么程度呢&#xff1f;到底應該怎么學&#xff1f;這期我給大家來做一個簡單回答&#xff0c;首先單純站在 An…

JDK+Tomcat搭建JSP運行環境--JSP基礎

一、搭建JSP運行環境之前需要了解的基本知識 配置JSP運行環境之前&#xff0c;我們需要了解JSP的運行機制。只有了解JSP運行機制后&#xff0c;我們才能知道為什么要搭建JSP運行環境?如何去搭建JSP運行環境?為什么要配置Tomcat、JDK&#xff1f; JSP(Java Sever Page)即Java服…

Docker容器的自動化監控實現

本文由 網易云 發布。 近年來容器技術不斷成熟并得到應用。Docker作為容器技術的一個代表&#xff0c;目前也在快速發展中&#xff0c;基于 Docker的各種應用也正在普及&#xff0c;與此同時 Docker對傳統的運維體系也帶來了沖擊。我們在建設運維平臺的過程中&#xff0c;也需…

robotframework 常用關鍵字

標準庫 第三方庫 其他庫轉載于:https://www.cnblogs.com/Chamberlain/p/10729054.html

身份證的驗證

var Wi [ 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2, 1 ]; // 加權因子 var ValideCode [ 1, 0, 10, 9, 8, 7, 6, 5, 4, 3, 2 ]; // 身份證驗證位值.10代表X function checkIdcard(idCard) { idCard trim(idCard);//去掉字符串頭尾空格 if (idCard.length 15…