HRBU_20211110训练(2019CCPC秦皇岛)
B - Decimal
题意
给一个整数n,判断1/n是否无穷小数,如果是,输出yes;如果不是,输出no.
思路
判断是否含有质因子2 和5,如果有则是可以整除,
否则不能。
代码
#include<stdio.h>
#include<iostream>
using namespace std;
int main()
{
int t;
cin>>t;
while(t--)
{
int n,flag=0;
cin>>n;
while(n%5==0)n/=5;
while(n%2==0)n/=2;
if(n==1)
cout<<"No"<<endl;
else
cout<<"Yes"<<endl;
}
}
C - Forest Program
题意
仙人掌图要求删除几条边,其中图中边都位于一个环中,没有复杂的环;让图变成树,问有几种方案。非常简单的题面。
思路
可以得到公式处于环中的边n,这是一个闭环,那么可以得到结果是(2^n)-1,如果是外边的边(不处于环中边)是2 ^ n.使用dfs()遍历求出有多少边位于环内。
代码
#include<stdio.h>
#include<iostream>
#include<vector>
#define ll long long
using namespace std;
const int maxn=5e5+10;
const int mod=998244353;
//void dfs() ll ksm(lla,llb) int main()
//定义一个最大值maxn,再定义一个容器edge,定义三个一维数组,int vis[],h[],a[]
vector<int> edge[maxn];
int a[maxn],h[maxn],vis[maxn];
int tot;
void dfs(int now,int f)
{
h[now]=h[f]+1;
vis[now]=1;
for(auto v:edge[now])
{
if(v!=f && vis[v]==1)
{
a[++tot]=h[now]-h[v]+1;
}
else if(!vis[v])
dfs(v,now);
}
vis[now]=2;
}
ll ksm(ll a,ll p)
{
ll ans=1;
while(p)
{
if(p&1)
ans = ans *a%mod;
a= a*a%mod;
p>>=1;
}
return ans;
}
int main()
{
int n,m;
scanf("%d %d",&n,&m);
for(int i=1;i<=m;i++)
{
int u,v;
scanf("%d %d",&u,&v);
edge[u].push_back(v);
edge[v].push_back(u);
}
for(int i=1;i<=n;i++)
{
if(!vis[i])
dfs(i,0);
}
ll ans=1;
for(int i=1;i<=tot;i++)
{
ans=ans*(ksm(2,a[i])-1)%mod;
m-=a[i];
}
ans = ans*ksm(2,m)%mod;
printf("%lld\n",ans);
}
D - Invoker
题意
有是个操作分别都是字符串,不同的字符串中有相同的字符,输入一串字符串,问最少要多少步操作才能完成
思路
先把所有字符的操作进行排序,进行全排列,可以得到每个字符的大小,在输入的时候记录每一个字符的不同,通过返回值可以直到相差几个字母,dp[i][j]=min(dp[i][j],dp[i-1][k]+get(a[now][j],a[pre][k]));最后求出最小值即可
代码
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string.h>
using namespace std;
const int maxn =1e5+10;
char s[maxn];
string a[26][15];
int vis[26];
int dp[maxn][10];
void init()
{
a['Y'-'A'][0]="QQQ";vis['Y'-'A']=1;
a['V'-'A'][0]="QQW";vis['V'-'A']=1;
a['G'-'A'][0]="QQE";vis['G'-'A']=1;
a['C'-'A'][0]="WWW";vis['C'-'A']=1;
a['X'-'A'][0]="QWW";vis['X'-'A']=1;
a['Z'-'A'][0]="WWE";vis['Z'-'A']=1;
a['T'-'A'][0]="EEE";vis['T'-'A']=1;
a['F'-'A'][0]="QEE";vis['F'-'A']=1;
a['D'-'A'][0]="WEE";vis['D'-'A']=1;
a['B'-'A'][0]="QWE";vis['B'-'A']=1;
for(int i=0;i<26;i++)
{
if(vis[i])
{
sort(a[i][0].begin(),a[i][0].end());//排序
int count =0;
do
{
a[i][++count]=a[i][0];//数组的第二位数计数排第几位
}while(next_permutation(a[i][0].begin(),a[i][0].end()));//全排列
vis[i]=count;
}
}
}
int get(string a,string b)
{
if(a==b)return 0;
if(a[1]==b[0] && a[2]==b[1]) return 1;
else if(a[2]==b[0])return 2;
else
return 3;
}
int main()
{
init();
while(~scanf("%s",s+1))
{
int len=strlen(s+1);
int len1,len2,ans=0x3f3f3f3f;
memset(dp,0x3f,sizeof(dp));
for(int i=1;i<=6;i++)dp[1][i]=3;
for(int i=2;i<=len;i++)
{
int now=s[i]-'A';len1=vis[now];//记录当前每一个值
int pre=s[i-1]-'A';len2=vis[pre];//记录前一个值的大小
for(int j=1;j<=len1;j++)
{
for(int k=1;k<=len2;k++)
{
dp[i][j]=min(dp[i][j],dp[i-1][k]+get(a[now][j],a[pre][k]));
}
}
if(i==len)
{
for(int i=1;i<=len1;i++)
ans = min(ans,dp[len][i]+len);
}
}
cout<<ans<<endl;
}
}
总结
今天是光棍节,祝单身人士节日快乐!哈哈哈哈哈!