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 照著敲了一遍略有一丟丟的感覺 但是實在是玄的很我要死了……來日再說……