1002 https://vjudge.net/contest/387998
题目:
https://vjudge.net/contest/387998#problem/B
思路:
题意是给一个等式,判断是否能在2-16进制内成立。成立输出进制数,不成立输出-1.
对于读入的每一个数字拆开(注意前导零),先储存最大的一位加一作为它成立的最小进制,然后再处理等式左右的结果(2-16进制),注意要与它成立的最小进制作比较,如果成立则输出进制,否则输出-1.
代码:
学习:https://blog.csdn.net/yangzijiangac/article/details/107844301
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1000;
const int mod=998244353;
ll max(ll a,ll b)
{
if(a>b) return a;
else return b;
}
int main()
{
char s[maxn],w[maxn];
w['0']=0;//进制
w['1']=1;
w['2']=2;
w['3']=3;
w['4']=4;
w['5']=5;
w['6']=6;
w['7']=7;
w['8']=8;
w['9']=9;
w['A']=10;
w['B']=11;
w['C']=12;
w['D']=13;
w['E']=14;
w['F']=15;
while(~scanf("%s",s))
{
ll len=strlen(s);
ll a=0,b=0,c=0;
ll ans=1,sum=0,flag=0,nnn,base=1;
for(ll i=len-1;i>=0;--i)
{
if(s[i]!='=' && s[i]!='+' && s[i]!='-' && s[i]!='*' && s[i]!='/')//排除符号
{
base=max(base,w[s[i]]);//最小进制
}
}
for(ll k=base+1;k<=16;++k)
{
ans=1,sum=0;
for(ll i=len-1;i>=0;--i)
{
if(s[i]!='=' && s[i]!='+' && s[i]!='-' && s[i]!='*' && s[i]!='/')
{
sum=w[s[i]]*ans+sum;
ans*=k;
}
else
{
if(s[i]=='=')
{
c=sum;
sum=0;
ans=1;
}
else
{
if(s[i]=='-') nnn=1;
if(s[i]=='+') nnn=2;
if(s[i]=='*') nnn=3;
if(s[i]=='/') nnn=4;
b=sum;
sum=0;
ans=1;
}
}
}
a=sum;
if((a+b)==c && nnn==2)
{
flag=1;
printf("%lld\n",k);
break;
}
else if((a-b)==c && nnn==1)
{
flag=1;
printf("%lld\n",k);
break;
}
else if((a*b)==c && nnn==3)
{
flag=1;
printf("%lld\n",k);
break;
}
else if(b!=0 && (a/b)==c && nnn==4 && (a%b)==0)
{
flag=1;
printf("%lld\n",k);
break;
}
}
if(flag==0)
printf("-1\n");
}
return 0;
}
1009 Divisibility
题目:
https://vjudge.net/contest/387998#problem/I
思路:
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int t;
cin>>t;
while(t--){
ll b,x;
cin>>b>>x;
if (b%x==1) {
cout<<"T"<<endl;
} else {
cout<<"F"<<endl;
}
}
return 0;
}
1006 A very easy graph problem
题目:
https://vjudge.net/contest/387998#problem/F
思路:
d[i][j]为i,j的最短路。第i条边的权值是2^i
第i条边的权值比前i-1条边权值和还大
代码:
学习:https://blog.csdn.net/tomjobs/article/details/107853226(原谅我吧,我真的不会,枯了)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 2e5 + 7;
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + 7;
int head[maxn],nex[maxn * 2],to[maxn * 2],tot;
ll val[maxn * 2];
int fa[maxn],a[maxn],ONE,ZERO;
int siz[maxn]; //总节点数
int f1[maxn],f2[maxn]; //为1和0的节点数
ll ans;
struct Edge {
int x,y;
ll z;
int id;
}edges[maxn];
int cmp(Edge a,Edge b) {
return a.id < b.id;
}
int findset(int x) {
if(fa[x]==x) return x;
return fa[x]=findset(fa[x]);
}
bool Union(int x,int y) {
int rx=findset(x),ry=findset(y);
if(rx!=ry) {
fa[rx]=ry;
return true;
}
return false;
}
void add(int x,int y,int z) {
to[++tot]=y;
nex[tot]=head[x];
val[tot]=z;
head[x]=tot;
}
void dfs(int x,int fa) {
if(a[x]) f1[x]=1;
else f2[x]=1;
for(int i=head[x];i;i=nex[i]) {
int v=to[i];
ll w=val[i];
if(v==fa) continue;
dfs(v,x);
f1[x]+=f1[v];
f2[x]+=f2[v];
//对于w这条边
ll num1=f1[v];//子树中1的个数
ll num0=ZERO-f2[v]; //其他树中0的个数
ans=(ans+num1*num0%mod*w%mod)%mod;
num1=ONE-f1[v]; //其他树中1的个数
num0=f2[v]; //子树中0的个数
ans=(ans+num1*num0%mod*w%mod)%mod;
}
}
int main() {
int T;scanf("%d",&T);
while(T--) {
int n,m;scanf("%d%d",&n,&m);
ll num=1;
tot=0;
ans=ONE=ZERO=0;
for(int i=1;i<=n;i++) {
scanf("%d",&a[i]);
if(a[i]) ONE++;
else ZERO++;
fa[i]=i;
f1[i]=f2[i]=0;
head[i]=0;
}
for(int i=1;i<=m;i++) {
scanf("%d%d",&edges[i].x,&edges[i].y);
num=num*2%mod;
edges[i].z=num;
edges[i].id=i;
}
sort(edges+1,edges+1+m,cmp);
int cnt=0;
for(int i=1;i<=m;i++) {
int x=edges[i].x,y=edges[i].y,z=edges[i].z;
if(Union(x,y)) {
cnt++;
add(x,y,z);add(y,x,z);
}
if(cnt>=n-1) break;
}
dfs(1,-1);
printf("%lld\n",ans);
}
return 0;
}