“今日头条杯”2018届湖北省大学程序设计竞赛
总体概述:
总过题数:6/10
A. Srdce and Triangle
- 完成
初中数学题。
等边三角形内一个点,旋转构造全等三角形,相连各点后形成新的等边三角形。
思路非常简单。
三个角减去60度排序输出即可。
#include<bits/stdc++.h>
using namespace std;
int main() {
double a, b, c;
while (cin >> a >> b >> c) {
double num[5];
num[0] = a - 60;
num[1] = b - 60;
num[2] = c - 60;
sort(num, num + 3);
printf("%.4f %.4f %.4f\n", num[0], num[1], num[2]);
}
return 0;
}
B. Salty Fish Go!
- 完成
看不懂的数学期望题,题面被队友找出来有问题。
D. Who killed Cock Robin
- 完成
n个节点的树内找连通子图。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=2e5+10;
const int p=1e7+7;
ll dp[maxn],dp1[maxn];
vector<int>G[maxn];
void add(int x,int y)
{
G[x].push_back(y);
G[y].push_back(x);
}
ll qpow(ll a,ll n)
{
ll ans=1;
while(n) {
if(n&1) ans=ans*a%p;
a=a*a%p;
n>>=1;
}
return ans;
}
void dfs(int u,int fa)
{
dp[u]=1;dp1[u]=0;
ll ans=1,siz=0,ans1=0;
for(auto v:G[u])
{
if(v==fa) continue;
dfs(v,u);siz++;
ans=ans*(1+dp[v])%p;
}
//cout<<" "<<ans<<" "<<siz<<" "<<u<<endl;
if(siz) {
dp[u]=ans;
}
}
int main()
{
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
int n;cin>>n;
for(int i=1;i<n;i++)
{
int x,y;cin>>x>>y;
add(x,y);
}
dfs(1,1);
ll ans=0;
for(int i=1;i<=n;i++)
ans=(ans+dp[i])%p;
cout<<ans<<endl;
return 0;
}
E. DoveCCL and Resistance
- 完成
构造题,好像思想主要是递归。
F. Flower Road
- 完成
暴力模拟,简单dp。
因为牛客评测机问题,改了数据范围,导致暴力算法明显超时,但还是大部分人的解答(应该也是正解,分块太麻烦了)。
卡常。
队友的首次提交如果IO流改成scanf就能过去。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=2e3+10;
ll dp[maxn][maxn];
int a[maxn][maxn],b[maxn][maxn];
int main()
{
// ios_base::sync_with_stdio(false);
// cin.tie(nullptr);
// cout.tie(nullptr);
int n,m;scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
scanf("%d",&a[i][j]);
while(m--)
{
int x,y,l;scanf("%d%d%d",&x,&y,&l);
for(int i=x;i<=x+2*l-1;i++)
for(int j=y;j<=y+2*l-1;j++)
b[i][j]=a[i][j];
for(int i=x;i<=x+l-1;i++)
for(int j=y;j<=y+l-1;j++)
a[i][j]=b[i+l][j];
for(int i=x+l;i<=x+2*l-1;i++)
for(int j=y;j<=y+l-1;j++)
a[i][j]=b[i][j+l];
for(int i=x;i<=x+l-1;i++)
for(int j=y+l;j<=y+2*l-1;j++)
a[i][j]=b[i][j-l];
for(int i=x+l;i<=x+2*l-1;i++)
for(int j=y+l;j<=y+2*l-1;j++)
a[i][j]=b[i-l][j];
}
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
dp[i][j]=max(dp[i][j-1],dp[i-1][j])+a[i][j];
printf("%lld\n",dp[n][n]);
//cout<<dp[n][n]<<endl;
return 0;
}
G. Coins
- 完成
模拟,纯模拟。
有点小思维。
爷终于在赛场上出了有效的思维了。
#include<bits/stdc++.h>
#define INF 1e18
using namespace std;
const int maxn = 200000 + 10;
typedef long long ll;
int main() {
ll T, x, y, z, n, cnt, t, temp, sum, ans;
cin >> T;
while (T--) {
cin >> n >> x >> y >> z;
ans = INF;
//设置ans,用min(ans,temp+cnt)更新ans
temp = 0;
//记录n变为当前值(n+ky)所经过的轮数
sum = 0;
//记录当前现有硬币数
while (1) {
// cout << "temp:" << temp << " ans:" << ans << " sum:" << sum << endl;
//cout << "n:" << n << " cnt:" << cnt << endl;
if (temp >= ans)
break;
//如果之前找到的最小局数(ans=temp+cnt)已经比现在的temp(记录n变为当前值(n+ky)所经过的轮数)要小了,说明绝对不用再循环下去了。
cnt = ((z - sum) % n) ? ((z - sum) / n + 1) : (z - sum) / n;
//cnt记录当前temp下,不用x换y需要的剩余局数。
ans = min(ans, temp + cnt);
//用当前状态下的temp(已经过轮数)+cnt(剩余轮数)更新ans。因为有这个更新,其实我的算法就是轮遍所有情况寻找最优,只不过设置跳出循环的条件巧妙了点。
if (sum >= x) {
//够的话就换掉,以便运算下一情况(更改n)
t = sum / x;
n += y * t;
sum -= t * x;
} else {
//不够就通过更新temp直到够换。
cnt = ((x - sum) % n) ? ((x - sum) / n + 1) : (x - sum) / n;
sum += cnt * n;
temp += cnt;
}
}
cout << ans << endl;
}
}
H. GSS and Simple Math Problem
- 完成
高精度大数,PY/Java。
n = eval(input())
ans = 1
for i in range(0, n):
a = eval(input())
ans = ans * a
print(ans)
I. Five Day Couple
- 完成
区间内数字取异或最大。
字典树。
题意非常裸。
错误点在于
范围要开到32+,不能只是32。
因为字典树要遍历到最后一层后面那一层(-1)才行,所以要多开点。
#include <bits/stdc++.h>
typedef long long ll;
const int MAXN = 1e5 + 10;
int tr[MAXN*33][2], root[MAXN], ridx[MAXN*33];
int idx;
int a[MAXN];
void insert(int x, int i)
{
root[i] = ++idx;
int u = root[i], p = root[i - 1];
ridx[u] = i;
for (int k = 31; ~k; --k)
{
int kbit = x >> k & 1;
tr[u][kbit] = ++idx; ridx[idx] = i;
tr[u][kbit ^ 1] = tr[p][kbit ^ 1];
u = tr[u][kbit], p = tr[p][kbit];
}
}
int query(int x, int l, int r)
{
int u = root[r];
ll ans = 0;
for (int k = 31; ~k; --k)
{
int kbit = x >> k & 1;
if (tr[u][kbit ^ 1] && ridx[tr[u][kbit ^ 1]] >= l) ans = ans << 1 | (kbit ^ 1), u = tr[u][kbit ^ 1];
else ans = ans << 1 | kbit, u = tr[u][kbit];
}
return ans ^ x;
}
int main()
{
int n; scanf("%d", &n);
for (int i = 1; i <= n; ++i)
{
scanf("%d", &a[i]);
insert(a[i], i);
}
int m; scanf("%d", &m);
while (m--)
{
int b, l, r; scanf("%d%d%d", &b, &l, &r);
printf("%lld\n", query(b, l, r));
}
return 0;
}
J. Avengers: Infinite War
- 完成
可持久化并查集。
K. GSS and Rating Calaulation
- 完成
看不懂,没CF网页上的公式我觉得完全做不了啊。
赛时榜单1/21。