2022第十四届四川省ACM(补题:B、F、H、K)

B:https://ac.nowcoder.com/acm/contest/42105/B

这题的翻译是真的有点绕,

翻译:一个商家开发了一个看起来正常但却是黑心的网站,这个网站里面有N个网页,每个网页下面有通向其他网页的链接。p(i,j)[i<j]:表示第i个网页通向第j个网页,这里还有可能去第j个网页的概率,然而,顾客必须要在一个网页里面购买东西(题目说了,顾客只会买一次,因为顾客不是呆瓜,不会再上一次当),问:这个顾客在网页买东西的概率分别是多少?

解析:这题可以采用有向图的方法求解,连边操作是非常简单的,重点就在于,怎么求每个网页的概率?然而经过反复推敲,一次次的推演,终得一个算法。

图解:

代码:

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int t,n,k;
struct Node{
	int to;
	double v;
};
double p[N];
vector<Node>e[N];
int main(){
	cin>>t;
	while(t--){
		cin>>n;
		for(int i=0;i<=n;i++) e[i].clear(),p[i]=0;
		for(int i=1;i<n;i++){
			cin>>k;
			while(k--){
				int x;double y;cin>>x>>y;
				e[i].push_back({x,y});
			}
		}
		p[1]=1.0;
		for(int i=1;i<=n;i++){
			double op=1.0;
			for(auto x:e[i]){
				p[x.to]+=p[i]*x.v;
				op-=x.v;
			}
			p[i]*=op;
			printf("%.10lf ",p[i]);
		}
		puts(" ");	
	}
}

F:https://ac.nowcoder.com/acm/contest/42105/F

因为缺乏数论的知识,确实比较难想到找质数即可;

 图中Pi代表的是质数,如果我们能够找到特定数量的质数,那么一定就可以找到这个x

代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int t,n;

bool is_pre(ll x){
	if(x<2) return false;
	if(x==2) return true;
	for(int i=2;i*i<=x;i++)
		if(x%i==0) return false;
	return true;
}

/*如果能够找到三个素数,因为由于x是素数的乘积,那么肯定存在素数的对乘,3+3=6,6个因子+1和x本身共有8个因子   */
int main(){
	cin>>t;
	while(t--){
		cin>>n;
		ll p1=1+n;//每次+n满足每个素数之差不小于n
		while(is_pre(p1)==false) p1++;
		ll p2=p1+n;
		while(is_pre(p2)==false) p2++;
		ll p3=p2+n;
		while(is_pre(p3)==false) p3++;
		if(p1*p1>p3) cout<<p1*p2*p3<<endl;/*如果找不到,则说明只存在三个不同的素数,此时的乘积就是最小*/
		else cout<<p1*p1*p1*p2<<endl;/*为什么是pow(p1,3),因为在x中,就存在2个p1的对乘和一个p1和p3的乘法对,再加1和x本身,共有8个因子*/
	}
}

H:https://ac.nowcoder.com/acm/contest/42105/H

呜呜,真的意难平!

大致翻译:一个人创造了一个容器,声称自己的容器存的东西,一定不会有重复的,你想反驳他的观点,然后他就让你来测试他的容器,叫你输出这个容器里面重复东西的次数。

样例解释:

 代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int t;

void Done(){
	int n,m,k;
	cin>>n>>m;
	for(int i=1;i<=n;i++) cin>>k;
	int ans=0;   unordered_map<string,int>e;
	for(int i=1;i<=m;i++){
		string s;
		for(int j=1;j<=n;j++){cin>>k;  s+=k;}
		ans+=e[s];	e[s]++;
	}
	cout<<ans<<endl;
}

int main(){
	cin>>t;
	while(t--)	Done();
}

K:https://ac.nowcoder.com/acm/contest/42105/K

解析:

K题讲的是,给了三个钟表指针,第二个的指针旋转定点是第一个指针的针头,第三个则是第二个的针头,问经过t秒后,第三个指针头在什么位置。

这题就很简单,但需要注意精度的问题,我们每次依次算每个旋转顶点,那么位置则可以由第三个旋转顶点求出。

图解:

代码:

#include<bits/stdc++.h>
using namespace std;
const double PI=2*3.14159265358979;//关于PI的值,一定要多取几位提高精度
double t,l1,l2,l3,t1,t2,t3;
//每个角度都可以通过时间算出来
int main(){
	cin>>t>>l1>>l2>>l3>>t1>>t2>>t3;
	double x1,x2,x3,y1,y2,y3,x,y;
	y1=l1*cos(t/t1*PI),y2=l2*cos(t/t2*PI),y3=l3*cos(t/t3*PI);
	x1=l1*sin(t/t1*PI),x2=l2*sin(t/t2*PI),x3=l3*sin(t/t3*PI);
	x=x1+x2+x3,y=y1+y2+y3;
	printf("%.10lf %.10lf",x,y);
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值