--------------------省赛入口------------------------
String Freshman
对于子串T,去匹配S的时候,若出现字母被重复利用,那么匹配S得到的答案肯定是错的; 只有当子串T的字母都不和首字母相同时,匹配主串时才能相同。 另一种思路: 用kmp算法求子串的最长公共前后缀。
#include <bits/stdc++.h>
using namespace std;
int m,p[100005];
char s[100005];
void pre()
{
p[1]=0;int j=0;
for(int i=1;i<m;i++)
{
while(j>0&&s[j+1]!=s[i+1])
j=p[j];
if(s[i+1]==s[j+1])
j++;
p[i+1]=j;
}
}
int main()
{
cin>>m;
cin>>(s+1);
pre();
int flag=0;
for(int i=1;i<=m;i++)
{
if(p[i])
{
flag=1;break;
}
}
if(flag)
cout<<"Wrong Answer"<<endl;
else
cout<<"Correct"<<endl;
return 0;
}
没想到只是个1000难度的搜索题而已。
#include <bits/stdc++.h>
#define ll long long
using namespace std;
ll a,b,ans,path[1005];
bool flag;
void dfs(ll x,ll step)
{
path[step]=x;
if(x==b)
{
cout<<"YES"<<endl;
flag=1;
cout<<step<<endl;
for(int i=1;i<=step;i++)
{
cout<<path[i]<<" ";
}
cout<<endl;
return;
}
if(x>b)
return;
dfs(x*2,step+1);
dfs(x*10+1,step+1);
}
int main()
{
cin>>a>>b;
dfs(a,1);
if(!flag)
{
cout<<"NO"<<endl;
}
return 0;
}
J. Grammy and Jewelry
坏习惯的弊端还是显现出来了。 平常数组都开的很大,不会去注意空间的倍数关系,最后自己都忘了。
#include <bits/stdc++.h>
using namespace std;
const int inf=0x3f3f3f3f;
const int N=6100;
int n,m,t,a[N],head[N],cnt,dist[N],dp[N];
bool vis[N];
struct node
{
int to,nxt,dis;
}e[N];
void add(int from,int to)
{
e[++cnt].to=to;
e[cnt].dis=1;
e[cnt].nxt=head[from];
head[from]=cnt;
}
struct nd
{
int id,dis;
bool operator<(const nd &a)const
{
return a.dis<dis;
}
};
void dij()
{
priority_queue<nd>q;
q.push(nd{1,0});
for(int i=1;i<=n;i++)
dist[i]=inf;
dist[1]=0;
while(!q.empty())
{
nd u=q.top();q.pop();
int now=u.id;
if(vis[now]) continue;
vis[now]=1;
for(int i=head[now];i;i=e[i].nxt)
{
int v=e[i].to;
if(dist[v]>dist[now]+e[i].dis)
{
dist[v]=dist[now]+e[i].dis;
if(!vis[v]) q.push(nd{v,dist[v]});
}
}
}
}
signed main()
{
cin>>n>>m>>t;
for(int i=2;i<=n;i++)
cin>>a[i];
for(int i=1;i<=m;i++)
{
int u,v;cin>>u>>v;
if(u==v) continue;
add(u,v);add(v,u);
}
dij();
for(int i=2;i<=n;i++) dist[i]*=2;
for(int i=2;i<=n;i++)
for(int j=dist[i];j<=t;j++)
{
dp[j]=max(dp[j],dp[j-dist[i]]+a[i]);
}
for(int i=1;i<=t;i++)
cout<<dp[i]<<" ";
cout<<endl;
return 0;
}
F. Fair Distribution
这个题真的要静下心好好想。 从分配机器人的数目,和每个机器人的能量数考虑。 一共20个能量数: 如果每个机器人分配3个,那么只需要7个机器人就可以;如果分配给8个,势必会增加权值; 如果6个机器人每人要分配4个,但在此情况下(20个能量棒),分配给5个机器人最佳。 同理: 观察 7 20 7 22 两组样例会发现巧妙之处。
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int inf=0x3f3f3f3f;
ll n,ans;
double m;
int main()
{
ll t;
scanf("%lld",&t);
while(t--)
{
scanf("%lld%lf",&n,&m);
if(n>m)
{
printf("%lld\n",(ll)(n-m));
continue;
}
ll x=ceil(m/n);
ans=inf;
while(1)
{
ll y=ceil(m/x);
ans=min(ans,(ll)(n-y+x*y-m));
if(y==1)
break;
x=ceil(m/(y-1));
}
printf("%lld\n",ans);
}
return 0;
}
C. Cube
今年再做这个题,用stl容器真的得心应手起来了。
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5+100;
struct node
{
int x,y,z;
}e[15];
set<int>s;
int main()
{
int t;cin>>t;
while(t--)
{
s.clear();
for(int i=1;i<=8;i++)
cin>>e[i].x>>e[i].y>>e[i].z;
int falg=0;
for(int i=1;i<=8;i++)
{
for(int j=1;j<=8;j++)
{
if(i==j)
continue;
int temp=(e[i].x-e[j].x)*(e[i].x-e[j].x)+(e[i].y-e[j].y)*(e[i].y-e[j].y)+(e[i].z-e[j].z)*(e[i].z-e[j].z);
if(temp==0)
falg=1;
s.insert(temp);
}
}
int ans=s.size();
if(falg||ans!=3)
cout<<"NO"<<endl;
else if(ans==3)
cout<<"YES"<<endl;
}
return 0;
}
|