A - Red Or Not
水题:n>=3200 输出 s,否则输出red
//#include<bits/stdc++.h>
#define ll long long
#include <stdio.h>
#include <algorithm>
#pragma GCC optimize(2)
using namespace std;
const int maxn=1e6+1000;
const int INF=1e9+7;
inline ll read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
ll n,m,x;
char str[100005];
int main()
{
scanf("%lld%s",&n,str);
if(n>=3200) printf("%s\n",str);
else printf("red\n");
return 0;
}
B - Resistors in Parallel
水题:题目给出 a1,a2,a3,ai , 输出 1/(1/a1+1/a2+.....1/ai),为了确保精度,首先将其通分化为一个分数,之后用double输出.
//#include<bits/stdc++.h>
#define ll long long
#include <stdio.h>
#include <algorithm>
#pragma GCC optimize(2)
using namespace std;
const int maxn=1e6+1000;
const int INF=1e9+7;
inline ll read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
ll n,m;
ll num[maxn];
ll gcd(ll a,ll b)
{
if(!b) return a;
return gcd(b,a%b);
}
int main()
{
scanf("%lld",&n);
for(int i=1;i<=n;i++) scanf("%lld",&num[i]);
ll lcm=num[1];
for(int i=2;i<=n;i++)
{
ll temp=gcd(lcm,num[i]);
lcm=lcm*num[i]/temp;
}
ll sum=0;
for(int i=1;i<=n;i++)
sum+=lcm/num[i];
// printf("%lld %lld\n",sum,lcm);
double res=(double)(lcm)*1.0;
double res1=(double)(sum)*1.0;
printf("%.6lf\n",res/res1*1.0);
return 0;
}
C - Alchemist
题目大意:给你n个数,你每次可以合并两个数,使这两个数变成(a+b)/2 ,然后再放回原数组,一直这么重复,最后数组将剩下一个数,问最后这个数的最大值是多少.
题目思路:贪心问题,因为每次合并,都会使每个数的贡献/2,那么就应该让小的先合并,大的合并次数越少,对结果贡献就越大
可以每次排序,因为n才50,也可以优先队列
AC(优先队列):
#include <bits/stdc++.h>
#define E 2.718
using namespace std;
typedef long long ll;
const ll INF=0x7f7f7f7f;
const int maxn=1e6+8;
const double eps=1e-10;
const ll mod=1000000007;
ll n,m,b;
struct node{
double w;
}num[150];
bool operator<(node a,node b)
{
return a.w>b.w;
}
int main()
{
priority_queue<node>q;
scanf("%lld",&n);
for(int i=1;i<=n;i++){
scanf("%lf",&num[i].w);
q.push(num[i]);
}
while(q.size()!=1)
{
node u=q.top();q.pop();
node u1=q.top();q.pop();
node now;now.w=(u.w+u1.w)*0.5;
q.push(now);
}
printf("%.7lf\n",q.top().w);
return 0;
}
D - Ki
题目大意:给你n个点,n-1条边,构成一颗树,这棵树以1为根节点,随后m行,每行 pi ,ai,表示以pi为根节点的子树的权值都加ai(包括pi),问最后每一个节点的权值是多少.
题目思路:我们把树遍历一遍就可以了,先预处理每个节点加了多少,经过这个节点后,sum+=当前节点权值,每次都更新当前节点权值.因为这是一棵树 复杂度O(N-1)
AC:
#include <bits/stdc++.h>
#define E 2.718
using namespace std;
typedef long long ll;
const ll INF=0x7f7f7f7f;
const int maxn=1e6+8;
const double eps=1e-10;
const ll mod=1000000007;
ll n,m,b;
struct node{
int e,next;
}edge[maxn];
int head[maxn];
ll cot[maxn];
ll res[maxn];
ll cnt=0;
void addedge(int u,int v)
{
edge[cnt]=node{v,head[u]};
head[u]=cnt++;
edge[cnt]=node{u,head[v]};
head[v]=cnt++;
}
void dfs(int u,int fa,ll sum)
{
res[u]=sum;
for(int i=head[u];i!=-1;i=edge[i].next)
{
int e=edge[i].e;
if(e!=fa)
dfs(e,u,sum+cot[e]);
}
}
int main()
{
memset(head,-1,sizeof(head));
scanf("%lld%lld",&n,&m);
for(int i=1;i<=n-1;i++)
{
int x,y;
scanf("%d%d",&x,&y);
addedge(x,y);
}
for(int i=1;i<=m;i++)
{
ll x,y;
scanf("%lld%lld",&x,&y);
cot[x]+=y;
}
addedge(0,1);
dfs(0,-1,0);
for(int i=1;i<=n;i++)
printf("%lld ",res[i]);
return 0;
}
F - String of Impurity
题目大意:给你两个字符串s,t,其中s可以复制为 s1,s2,s3,s4....sn,问当t是s复制的字符串的子序列时最小的长度
例子:s=contest t=son s2=contestcontest 当s复制两次时,t是s2的子序列并且最小长度为 contestcon =10
题目思路:如果同时n^2遍历两个字符串绝对会超时,我们就遍历一个字符串,我们遍历t,这时候需要一个东西辅助 ---- 序列自动机.我们用序列自动机存下s当前位置的下一个t的字符在哪,如果找不到那就需要复制一遍s,这时位置=t当前字符在s中第一次出现的位置,所以 预处理 t中字母在s中第一次出现的位置,无解条件,t中出现的字母s中没有出现
AC:
#include <bits/stdc++.h>
#define E 2.718
using namespace std;
typedef long long ll;
const ll INF=0x7f7f7f7f;
const int maxn=1e6+8;
const double eps=1e-10;
const ll mod=1000000007;
ll n,m,b;
bool viss[30];
char s[100005],t[100005];
int nex[100005][30];
int loca[30];// 标记初始位置
void restart(int len)
{
for(int i=1;i<=len+1;i++)
for(int k=1;k<=26;k++)
nex[i][k]=-1;
for(int i=len;i>=2;i--)
{
for(int k=1;k<=26;k++) nex[i-1][k]=nex[i][k];
nex[i-1][s[i]-'a'+1]=i;
}
}
int main()
{
bool f=false;
scanf("%s%s",s+1,t+1);
int lens=strlen(s+1),lent=strlen(t+1);
restart(lens);
for(int i=1;i<=lens;i++)
{
if(!viss[s[i]-'a'+1])
{
loca[s[i]-'a'+1]=i;
viss[s[i]-'a'+1]=true;
}
}
for(int i=1;i<=lent;i++)
if(viss[t[i]-'a'+1]==false)
{
f=true;
break;
}
if(f) printf("-1\n");
else
{
ll ans=0;// 次数与最后长度
ll st=loca[t[1]-'a'+1],peace=1;;
while(peace!=lent)
{
ll temp=t[peace+1]-'a'+1;
if(nex[st][temp]!=-1)
st=nex[st][temp];
else
{
st=loca[temp];
ans++;
}
peace++;
}
printf("%lld\n",ans*lens+st);
}
return 0;
}
F - Coincidence
还没做出来.....
总结:
昨天回去累了,下午5点睡觉到9.10.....起来之后 还剩半个小时结束比赛. 疯狂掉分ing...上午抽空补了一下发现不应该掉分的们这次比赛还是能做的,唉,不管怎么样掉了分就继续上,加油了ACMer