1. 程式人生 > >18-10-13 補題記錄

18-10-13 補題記錄

今天的訓練賽可以說充滿了烏龍……

1.A題 可能是最近搜尋做多了 ——BFS……還好隊友及時阻止了我……

2.C題 一看 異或嘛……最大的異或嘛……TLE……字典樹……

3.E題 一看 矩陣嘛……交換對吧……TLE……十字連結串列……

 

寫了三題 全是基礎的簡單題 讀得懂英文就可以寫的那種 就又要很喪了……

A、B、F 這裡暫時不寫了 都是簡單的

 

 

H - Pythagorean Triples   (CodeForces - 707C )

#include <iostream>
using namespace std;

int main()
{
	long long ab, k, m, a, b;
	long long n;
	while (cin>>n)
	{
		if (n < 3) { printf("-1\n"); continue; }
		k = 1; ab = n * n;

		for (a = 1; a <= n; a++)
		{
			if (ab % a == 0)
			{
				b = ab / a;
				if (a % 2 == b % 2 && a!=b)
				{
					if (a < b)
						swap(a, b);
					k = (a + b) / 2;
					m = (a - b) / 2;
					cout << k<<" "<< m << endl;
					break;
				}
			}
		}

	}
	return 0;
}

給出直角三角形的一邊 求另外兩條

初看 我覺得應該是打表了 但是!n最大可以1e9 仔細一想應該是勾股定理的應用 但是怎麼也想不出怎麼用

然後找了找部落格 n(2)=k(2)-m(2)=(k+m)(k-m) 這個是真心意識不到……

但是一旦想到了平方差公式 接下來就會變得非常的簡單

設A=k+m B=k-m

m=(A-B)/2 k=(A+B)/2

因為 三邊都是整數 所以A、B必須奇偶性相同 這個部落格我也只看到了這裡 下面也就瀏覽 但是那個做法我確實是學不來的 模模糊糊總覺得不明白 不如自己著手先弄弄

就試著枚舉了a b就用n(2)/a

然後迴圈到n是因為原來用的是ab然後想到a*b=ab 然後如果a>n了 就會迴圈兩遍一樣的 只是分別賦值給了a和b而已 也沒意思

現在一想 其實a<b那兩行也未必需要……

 

G - Bakery CodeForces - 707B

#include <iostream>
using namespace std;

const int inf = 2e9;
const int maxn = 100005;

int main()
{
	int n, m, k;
	while (cin >> n >> m >> k)
	{
		int u[maxn], v[maxn], l[maxn];
		for (int i = 0; i < m; i++)
		{
			cin >> u[i] >> v[i] >> l[i];
		}
		int g[maxn] = { 0 };
		for (int i = 0; i < k; i++)
		{
			int t;
			cin >> t;
			g[t] = 1;
		}
		int ans = inf;
		for (int i = 0; i < m; i++)
		{
			if (g[u[i]] != g[v[i]])
			{
				if (ans > l[i])
					ans = l[i];
			}
		}
		if (ans == inf)
			cout << -1 << endl;
		else
			cout << ans << endl;
	}
	return 0;
}

沒仔細看題,一直沒讀懂題意,完了之後也沒有動手做做寫寫……就覺得像是歐拉回路之類的……

坑爹呀!!!

一共n個城市,有m個道路,有k個倉庫,倉庫和商店不能開在同一個城市,求路徑最短。

所以 我們需要做的就是把每個沒有倉庫城市遍歷過去,再看一看有沒有道路直接到一個有倉庫的城市,求得最短的道路的值就可以了。為什麼不能通過一個有倉庫的城市到另一個沒有倉庫的城市呢,因為經過總不如直連這樣的意思嘛。

 

C - Hard problem CodeForces - 706C

#include<iostream>
#include<cstring>
#include<string>
#include<algorithm>
using namespace std;
const int maxn = 100010;
const long long inf = 1e15;
string str[maxn][2];
string s;
int c[maxn];
long long dp[maxn][2];

int main()
{
	int n, i;
	while (scanf("%d", &n) != EOF)
	{
		for (i = 0; i<n; ++i)
			scanf("%d", &c[i]);
		for (i = 0; i<n; ++i)
		{
			cin >> s;
			str[i][0]=s;
			reverse(s.begin(),s.end());
			str[i][1] = s;
		}
		for (i = 0; i<n; ++i)
			dp[i][0] = dp[i][1] = inf;
		dp[0][0] = 0; dp[0][1] = c[0];
		for (i = 1; i<n; ++i)
		{
			if (str[i][0] >= str[i - 1][0])
				dp[i][0] = dp[i - 1][0];
			if (str[i][1] >= str[i - 1][0])
				dp[i][1] = dp[i - 1][0] + c[i];
			if (str[i][0] >= str[i - 1][1])
				dp[i][0] = min(dp[i][0], dp[i - 1][1]);
			if (str[i][1] >= str[i - 1][1])
				dp[i][1] = min(dp[i][1], dp[i - 1][1] + c[i]);
			if (dp[i][1] == inf && dp[i][0] == inf)
				break;
		}
		if (i == n)
			printf("%I64d\n", min(dp[n - 1][0], dp[n - 1][1]));
		else
			printf("-1\n");
	}
	return 0;
}

字串DP 照著敲了一遍略有一丟丟的感覺 但是實在是玄的很我要死了……來日再說……