1. 程式人生 > >[atcoder]AtCoder Grand Contest 027題解

[atcoder]AtCoder Grand Contest 027題解

【題目連結】

A

【題解】

題意: 是把xx個糖果分給nn個人,一個人如果恰好分到aia_{i}個糖果就會高興。求最多使多少個人高興。

題解: 一定是優先滿足需求小的人,特判有額外的剩餘糖果。

時間複雜度:O(NlogN)O(NlogN)

【程式碼】

# include <bits/stdc++.h>
# define 	ll 		long long
using namespace std;
const int inf = 0x3f3f3f3f, INF = 0x7fffffff;
const ll  infll = 0x3f3f3f3f3f3f3f3fll, INFll =
0x7fffffffffffffffll; int read(){ int tmp = 0, fh = 1; char ch = getchar(); while (ch < '0' || ch > '9'){ if (ch == '-') fh = -1; ch = getchar(); } while (ch >= '0' && ch <= '9'){ tmp = tmp * 10 + ch - '0'; ch = getchar(); } return tmp * fh; } const int N = 110; int n, sum, num[N],
ans; int main(){ n = read(), sum = read(); for (int i = 1; i <= n; i++) num[i] = read(); sort(num + 1, num + n + 1); ans = 0; while (ans < n){ if (sum >= num[ans + 1]){ sum -= num[++ans]; } else break; } if (ans == n && sum != 0) ans--; printf("%d\n", ans); return 0
; }

B

【題解】

題意: 一條數軸上有nn個垃圾,全在正半軸上。OO點是垃圾桶。現在有一個機器人,一開始在OO點。它每移動格的代價為(k+1)2(k+1)^2kk為當前攜帶的垃圾數量。在移動到與垃圾座標相同時可以撿起垃圾,每次撿起/扔掉垃圾都要xx的代價(不能再非OO點扔垃圾)。求最小代價。

題解: 考試時以為一次一定取相鄰的一段,這顯然是錯的。

考慮貪心,行走的路線一定是先是走到最遠的點,在回來時不斷帶上其他的點。

一個點(座標p),如果在一趟路程中是第ii個取完的,那麼它的代價是:

(i2+3)p(i*2+3)*p如果i=1i=1

(i2+1)p(i*2+1)*p如果i&gt;1i&gt;1

所以遠的點被取的位置一定在近的點之前。

那麼我們列舉一共走的次數,那麼取的順序是唯一確定的。

於是就有了一個O(N2)O(N^2)的做法。

考慮優化由於i/j\lfloor i/j\rfloor只有i\sqrt{i}種取值,所以所有的垃圾被取的位置只會變換NlogNNlogN次。

時間複雜度O(NlogN)O(NlogN)

【程式碼】

# include <bits/stdc++.h>
# define 	ll 		long long
using namespace std;
const int inf = 0x3f3f3f3f, INF = 0x7fffffff;
const ll  infll = 0x3f3f3f3f3f3f3f3fll, INFll = 0x7fffffffffffffffll;
int read(){
	int tmp = 0, fh = 1; char ch = getchar();
	while (ch < '0' || ch > '9'){ if (ch == '-') fh = -1; ch = getchar(); }
	while (ch >= '0' && ch <= '9'){ tmp = tmp * 10 + ch - '0'; ch = getchar(); }
	return tmp * fh;
}
const int N = 201000;
int n;
ll x, p[N], ans = infll, sum[N];
int main(){
//	freopen(".in", "r", stdin);
//	freopen(".out", "w", stdout);
	n = read(), x = read();
	for (int i = 1; i <= n; i++) p[i] = read();
	int lim = n / 1000;
	sum[0] = n * x;
	for (int i = 1; i <= n; i++) sum[i] = x; 
	sum[1] += p[n] * 5; 
	for (int i = 1; i <= n; i++){
		int id = n - i + 1, nxt = 1, k = i - 1;
		bool flag = false;
		for (int j = 1; j <= k; j = nxt + 1){
			nxt = k / (k / j);
			int w = k / j + 1;
			if (j != 1 && flag == true){
				int las = k / (j - 1) + 1;
				sum[j] = sum[j] - p[id] * (2 * las + 1);
			}
			if (j >= lim || k / j == 1){
				sum[j] = sum[j] + p[id] * (2 * w + 1);
				flag = true;
			}
		} 
	} 
	for (int i = 1; i <= n; i++){
		sum[i] += sum[i - 1]; 
		if (i >= lim) ans = min(ans, sum[i]);
	}
	printf("%lld\n", ans);
	return 0;
}

C

【題解】

題意: 有一個圖,每個節點有一個字母aabb,在這個圖上,一條路徑表示一個字串(把點上的字母連起來)。現在問這個圖上的所有路徑是否能表示所有的只用aabb構成的字串。

題解: 原問題等價於尋找一個由重複的aabba-a-b-b構成的環,即這個環上每個點都與環上的一個aa與一個bb相鄰。

考慮把一個節點拆成兩種,一種是下一步要與當前點不同,另一種是下一步要與當前點相同。然後在新圖上跑tarjan,如果有環,則有解。

時間複雜度O(N+M)O(N+M)

【程式碼】

# include <bits/stdc++.h>
# define 	ll 		long long
using namespace std;
const int inf = 0x3f3f3f3f, INF = 0x7fffffff;
const ll  infll = 0x3f3f3f3f3f3f3f3fll, INFll = 0x7fffffffffffffffll;
int read(){
	int tmp = 0, fh = 1; char ch = getchar();
	while (ch < '0' || ch > '9'){ if (ch == '-') fh = -1; ch = getchar(); }
	while (ch >= '0' && ch <= '9'){ tmp = tmp * 10 + ch - '0'; ch = getchar(); }
	return tmp * fh;
}
const int N = 200010;
struct Edge{
	int data, next;
}e[N * 2];
int use[N][2], head[N], flag, n, m, place;
char s[N];
void build(int u, int v){
	e[++place].data = v; e[place].next = head[u]; head[u] = place;
}
void dfs(int x, int tag){
	use[x][tag] = 1;
	for (int ed = head[x]; ed != 0; ed = e[ed].next){
		if (use[e[ed].data][tag ^ 1] == 2) continue;
		if (tag == 1){
			if (s[e[ed].data] == s[x]) continue;
			if (use[e[ed].data][0] == false)
				dfs(e[ed].data, 0);
				else flag = true;
		}
		else {
			if (s[e[ed].data] != s[x]) continue;
			if (use[e[ed].data][1] == false)
				dfs(e[ed].data, 1);
				else flag = true;
		}
	}
	use[x][tag] = 2;
}
int main(){
//	freopen(".in", "r", stdin);
//	freopen(".out", "w", stdout);
	n = read(), m = read();
	scanf("\n%s", s + 1);
	for (int i = 1; i <= m; i++){
		int u = read(), v = read();
		build(u, v);
		build(v, u);
	}
	for (int i = 1; i <= n; i++){
		if (use[i][0] == 0) dfs(i, 0);
		if (use[i][1] == 0) dfs(i, 0); 
	}
	if (flag)
		printf("Yes\n");
		else printf("No\n");
	return 0;
}

D

【題解】

題面: 構造一個nnn*n的矩陣,其中的每一個數不能超過101510^15。使得存在一個數xx使任意相鄰的兩個數中%=x大\%小=x

題解: 考慮·一個x=1x=1的情況,若所有(x+y)%2=0(x+y)\%2=0的格子中各填一個不同的素數,在其他格子中填相鄰四個數的乘積(lcm)+1。那麼這一定是一個合法解。但是這樣做值域不夠。

考慮(x+y)%2=0(x+y)\%2=0的格子,對於左上-右下的對角線我們用前500個素數,左下-右上的對角線我們用第501到第1000個素數。格子中的數為對應的兩條對角線上對應質數的積。那麼每個格子的值一定不同。其他格子仍然為相鄰四格的lcm,由於相鄰四格中相鄰兩個一定有一條對角線相同,所以lcm為\sqrt{相鄰四格的乘積}

這樣的話,格子中最大的數不會超過4個第1000個質數的乘積,符合條件。

【程式碼】

# include <bits/stdc++.h>
# define 	ll 		long long
using namespace std;
const int inf = 0x3f3f3f3f, INF = 0x7fffffff;
const ll  infll = 0x3f3f3f3f3f3f3f3fll, INFll = 0x7fffffffffffffffll;
int read(){
	int tmp = 0, fh = 1; char ch = getchar();
	while (ch < '0' || ch > '9'){ if (ch == '-') fh = -1; ch = getchar(); }
	while (ch >= '0' && ch <= '9'){ tmp = tmp * 10 + ch - '0'; ch = getchar(); }
	return tmp * fh;
}
const int N = 100010;
ll mp[520][520
            
           

相關推薦

[atcoder]AtCoder Grand Contest 027題解

【題目連結】 A 【題解】 題意: 是把xxx個糖果分給nnn個人,一個人如果恰好分到aia_{i}ai​個糖果就會高興。求最多使多少個人高興。 題解: 一定是優先滿足需求小的人,特判有額外的剩餘糖果。 時間複雜度:O(NlogN)O(NlogN)O(Nlog

Atcoder Grand Contest 002 題解

push_back 個人選擇 first box 可能 getc 等於 clear const A - Range Product 經過0答案肯定是0,都是正數肯定是正數,都是負數的話就奇負偶正。 //waz #include <bits/stdc++.h>

Atcoder Grand Contest 003 題解

位置 發現 clu cpp 模擬 gii icu define -a A - Wanna go back home 如果有S就必須要有N,反之亦然,如果有E必須要有W,反之亦然。判斷一下就好了。 //waz #include <bits/stdc++.h>

AtCoder Grand Contest 013 題解

fine esp square == ask air %d nis 就是 A - Sorted Arrays 貪心,看看不下降和不上升最長能到哪,直接轉移過去即可。 1 //waz 2 #include <bits/stdc++.h> 3 4 us

AtCoder Grand Contest 015 題解

pan gin ken -- 出現 style 地方 連通塊 發現 A - A+...+B Problem 可以取到的值一定是一段區間。所以答案即為max-min+1 1 //waz 2 #include <bits/stdc++.h> 3 4 u

Atcoder Grand Contest 021 題解

Problem A. (此處省略)反正怎麼搞都行了。。。 Problem B. 對於每個點,列舉其他點,那麼選的點一定是在垂直平分線的一側。由於R 特別大,所以可以把這個垂直平分線移到這個點上,就相當於一堆可行極角區間求交 也可以O(nlogn),大概是把凸

AtCoder Grand Contest 031 簡要題解

isp href uil 出現 mat false tor 每次 spa AtCoder Grand Contest 031 Atcoder A - Colorful Subsequence description 求\(s\)中本質不同子序列的個數模\(10^9+7\)。

AtCoder Grand Contest 013D: Piling Up 題解

情況 之前 include out fin fine del ons etc 題意簡化: [luogu] Piling Up 一開始有n個顏色為黑白的球,但不知道黑白色分別有多少,m次操作,每次先拿出一個球,再放入黑白球各一個,再拿出一個球,最後拿出的球按順序排列會形成一個

AtCoder Grand Contest 020 C - Median Sum

CI https TE ems and fin sub oot tco 題目:here 題解:要轉化一下,找所有子集的中間值,等價於找一個子集,滿足這個子集的和最接近整個序列的和的一半。也就是一個背包判斷可行性的問題。重點來了,bitset優化,至於為什麽?我也不懂啊啊啊

[Atcoder Grand Contest 001] Tutorial

IV AI display aps span col tin lap nbsp Link: AGC001 傳送門 A: #include <bits/stdc++.h> using namespace std; long long res=0; int n

AtCoder Grand Contest 024 Problem E(動態規劃)

stand 之間 graph ret scan 慢慢 rap and there www.cnblogs.com/shaokele/ AtCoder Grand Contest 024 Problem E   Time Limit: 2 Sec   Memory Lim

AtCoder Grand Contest 006 F - Blackout

sin 所在 long long || 如果 open int 雙向 mem Description 在 \(n*n\) 的棋盤上給出 \(m\) 個黑點,若 \((x,y)\),\((y,z)\) 都是黑點,那麽 \((z,x)\) 也會變成黑點,求最後黑點的數量 題面

AtCoder Grand Contest #026 C - String Coloring

暴力 input 很好 left rgs map() paint int() letters Time Limit: 3 sec / Memory Limit: 1024 MB Score : 600600 points Problem Statement Y

AtCoder Grand Contest 007

mem ssi || 狀態 puts def end tor ace AtCoder Grand Contest 007 A - Shik and Stone 翻譯 見洛谷 題解 傻逼玩意 #include<cstdio> int n,m,tot;char ch

AtCoder Regular Contest 103 題解

print -s struct namespace type iostream con clas inline C-/\/\/\ #include<algorithm> #include<iostream> #include<cstdlib&g

AtCoder Grand Contest 011

判斷 define 開機 %s square d+ 更新 getc 在一起 AtCoder Grand Contest 011 upd:這篇咕了好久,前面幾題是三周以前寫的。。。 AtCoder Grand Contest 011 A - Airport Bus 翻譯 有\

AtCoder Grand Contest 001 C Shorten Diameter 樹的直徑

題意 給你一棵樹,每次可以刪除一個葉子節點,求最少需要多少次操作可以讓樹的直徑\(<=k,(n <= 2e3)\) 首先觀察資料範圍是可以接受\(O(n^2)\)的演算法的 我們考慮列舉每個點作為樹的根 統計這個點一定在直徑上時要刪多少點 如果\(k\)是偶數,那麼深度大於\(

AtCoder Grand Contest 006 C:Rabbit Exercise

題目傳送門:https://agc006.contest.atcoder.jp/tasks/agc006_c 題目翻譯 數軸上有\(N\)只兔子,從\(1\)到\(N\)編號,每隻兔子初始位置是\(x_i\)。現在兔子們要開始做運動,運動都有\(M\)個步驟,對於第\(i\)個步驟,我們用\(a_i\)來

AtCoder】Dwango Programming Contest V題解

tco first rotation ram tmp pre 證明 必須 隊列 A - Thumbnail 根據題意寫代碼 #include <bits/stdc++.h> #define fi first #define se second #define p

AtCoder Grand Contest 014 E:Blue and Red Tree

make 開始 n-1 不可 task blog 應該 space find 題目傳送門:https://agc014.contest.atcoder.jp/tasks/agc014_e 題目翻譯 有一棵有\(N\)個點的樹,初始時每條邊都是藍色的,每次你可以選擇一條由藍色