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);
}