Problem C: Coolest Ski Route
题目大意:在有向图里找一个最长路,没有入点的是起点,没有出点的是终点。用记忆化搜索
#include <bits/stdc++.h>
#define mm(a) memset(a, 0, sizeof(a));
using namespace std;
const int N = 5e3 + 7;
int n, m;
int Map[N][N];
int dp[N];
int vis[N];
int cnt[N];
void inti()
{
mm(Map);
mm(vis);
mm(dp);
mm(cnt);
}
int dfs(int op)
{
if(vis[op]) return dp[op];
vis[op] = 1;
for(int i = 1; i <= n; i ++)
{
if(Map[op][i]) dp[op] = max(dp[op], dfs(i) + Map[op][i]);
}
return dp[op];
}
int main()
{
int m;
cin >> n >> m;
int u, v, w;
int i, j, k;
inti();
for(i = 1; i <= m; i ++)
{
cin >> u >> v >> w;
cnt[v] ++;
Map[u][v] = max(Map[u][v], w);
}
int Max = 0;
for(i = 1; i <= n; i ++)
{
if(cnt[i] == 0)
Max = max(Max, dfs(i));
}
cout << Max << endl;
return 0;
}
/*
5 5
1 2 15
2 3 12
1 4 17
4 2 11
5 4 9
*/
Problem F: Fighting Monsters
思路:因为要求最后要1嘛,所以最后一个一定是1 ,0,然后再往前找,然后就非常惊奇地发现是个斐波那契数列,然后还是两列差一位的,就比如11,12,23,35,58;然后用vector数组实现,vector一维里存的是斐波那契,二维里存的是原数列中的下标。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e5 + 7;
const int INF = 0x3f3f3f3f;
int f[40] = {1, 1, 2, 3, 5, 8};
int a[N];
vector<int>v[40];
void inti()
{
for(int i = 4; i <= 31; i ++)
{
f[i] = f[i - 1] + f[i - 2];
}
}
int main()
{
inti();
int n;
cin >> n;
for(int i = 1; i <= n; i ++)
{
cin >> a[i];
int tmp = lower_bound(f + 1, f + 32, a[i]) - f;
if(f[tmp] == a[i])
{
v[tmp].push_back(i);
// cout << f[tmp] << "*" << endl;
}
}
int ansx = INF, ansy = INF;
for(int i = 1; i <= 31; i ++)
{
if(v[i].size() == 0) continue;
if(v[i + 1].size() == 0) continue;
if(ansx > v[i][0])
{
ansx = v[i][0];
ansy = v[i + 1][0];
// cout << ansx << "&&" << ansy << endl;
}
}
if(v[1].size() > 1)
{
if(ansx > v[1][0])
ansx = v[1][0], ansy = v[1][1];
}
if(ansx != INF) cout << ansx << " " << ansy << endl;
else cout << "impossible\n";
return 0;
}
D - Down the Pyramid
题意:给你一层金字塔,然后找下一层金字塔的排布会有几种情况。
思路:知道下一层的第一个是多少,后边的加加减减就都可以知道了,所以要判断后边的所有的数都不能小于等于0,然后又发现如果设第一个数为x的话,奇数列是常数 - x, 偶数列是x - 常数;然后就分奇偶讨论,找到奇偶的最大值和最小值的范围然后相减加一(因为要两头)就是答案。
#include<bits/stdc++.h>
#define mm(a) memset(a, 0, sizeof(a))
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int N = 1e6 + 7;
int a[N];
int main()
{
ios::sync_with_stdio(0);
cin.tie();
cout.tie();
int n;
cin >> n;
int i;
for(i = 1; i <= n; i ++)
{
cin >> a[i];
}
ll now = 0, Min = 0, Max = INF*2;
for(i = 1; i <= n; i ++)
{
if(i%2)
{
now = a[i] - now;
Max = min(Max, now);
}
else
{
now = a[i] - now;
Min = max(Min, -now);
}
}
if(Max < 0 || Min < 0 || Max - Min + 1 < 0) cout << 0 << endl;
else cout << Max - Min + 1 << endl;
return 0;
}
题意:给你俩浮点数,判断能不能用素数表示;
思路:给你x, y, 找到素数p, q,使x/y = p/q;
先让x,y乘1e5,然后除掉它们的最大公约数,再判断最后得到的数是不是素数,要注意如果最后是1 1的话,要改成2 2输出,需要特判。
答案:
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5;
bool prime(int x)
{
if(x <= 1) return false;
int i;
for(i = 2; i <= x/i; i ++)
{
if(x%i == 0) return false;
}
return true;
}
int gcd(int a, int b)
{
return !b ? a : gcd(b, a%b);
}
int main()
{
int n;
cin >> n;
while(n --)
{
double a, b;
scanf("%lf %lf", &a, &b);
a *= N ;
b *= N;
// cout << b << endl;
int aa = (int)(a + 0.5), bb = (int)(b + 0.5);
// cout << aa << "&" << bb << endl;
int t = gcd(aa, bb);
aa /= t, bb /= t;
// cout << t << "*" << aa << "*" << bb << endl;
if(aa == 1 && bb == 1) cout << 2 << " " << 2 << endl;
else
{
if (prime(aa) && prime(bb))
cout << aa << " " << bb << endl;
else
cout << "impossible\n";
}
}
return 0;
}