vp一下四川省赛 勉强出了五个题
K. Kooky Clock
题意
给你三条线段,第二条与第一条相连,第三条与第二条相连,从内到外三条线段的长度、速度不同,问经过T秒后最外层指针停在什么位置(坐标)
思路
简单的数学题 ,直接计算每个指针所停位置的横纵坐标,相加即可。
Code
#include<bits/stdc++.h>
using namespace std;
double T;
double t[4],l[4];
const double pi=acos(-1.0);
int main()
{
cin>>T;
for(int i=1;i<=3;i++)
cin>>l[i];
for(int i=1;i<=3;i++)
cin>>t[i];
double o[4],x[4],y[4];
for(int i=1;i<=3;i++)
{
o[i]=T*2*pi/t[i];
x[i]=l[i]*sin(o[i]);
y[i]=l[i]*cos(o[i]);
}
printf("%.10lf %.10lf\n",x[1]+x[2]+x[3],y[1]+y[2]+y[3]);
}
F. Factor Difference
题意
一个整数x满足,x有至少八个因子,任何两个不同的因子相差不小于n,给定n,求最小的x
思路
简单数学题,最小的x肯定因子最少且最小,就设x有8个因子,则x有三个不同的质因子,由于要求两个不同的因子相差不小于n,在质数表里寻找最小的三个相差不小于n的质数即可。(注意特判n==1)
Code
#include <bits/stdc++.h>
#define IOS std::ios::sync_with_stdio(false);std::cin.tie(0);
#define ll long long
#define db double
#define PII pair<int, int>
#define ALL(x) x.begin(), x.end()
#define debug(x) cerr<<#x<<"->"<<x<<endl
using namespace std;
const int maxn=1e6+10;
const int INF=0x3f3f3f3f;
const db esp=1e-12;
int prime[maxn],cnt;
bool vis[maxn];
void Eular()
{
for(int i=2;i<=maxn;i++)
{
if(!vis[i]) prime[++cnt]=i;
for(int j=1;j<=cnt;j++)
{
if(i*prime[j]>maxn) break;
vis[i*prime[j]]=1;
if(i%prime[j]==0) break;
}
}
}
void solve()
{
int n; cin>>n;
if(n==1)
{
cout<<24<<endl;
return ;
}
int res1=1+n,res2=1+2*n,res3=1+3*n;
bool vis1,vis2,vis3; vis1=vis2=vis3=0;
for(int i=1;i<=cnt;i++)
{
if(prime[i]>=res1&&!vis1) res1=prime[i],vis1=1;
if(prime[i]-res1>=n&&!vis2) res2=prime[i],vis2=1;
if((prime[i]-res2>=n)&&!vis3)
{
res3=prime[i];
break;
}
}
ll res=1ll*res1*res2*res3;
cout<<res<<endl;
}
int main()
{
Eular();
int tt;
cin>>tt;
while(tt--) solve();
system("pause");
return 0;
}
B. Business website
题意
有个奸商,设计了n个网站,当你浏览某个网站时可能会有一定概率跳转到其他网站,且一定有几个网站不会接着跳转。给你n,以及每个网站能够跳转到的网站和概率,问用户停在每个网站的概率
思路
考虑留在第i个网站的概率为res[i],初始化为1,每条边{i,j}对i的贡献为减去res[i]*w[u],即从网站i离开的概率,对j的贡献为加上res[i]*w[u],即为到达网站j的概率。一开始写了个dfs,T了。后来想想其实暴力枚举每一条边即可。
Code
#include <bits/stdc++.h>
#define IOS std::ios::sync_with_stdio(false);std::cin.tie(0);
#define ll long long
#define db double
#define PII pair<int, int>
#define ALL(x) x.begin(), x.end()
#define debug(x) cerr<<#x<<"->"<<x<<endl
using namespace std;
const int maxn=1e6+10;
const int INF=0x3f3f3f3f;
const db esp=1e-12;
int head[maxn],to[maxn*2],nex[maxn*2],idx;
db w[maxn*2],res[maxn];
void addedge(int u,int v,db x)
{
to[idx]=v,w[idx]=x,nex[idx]=head[u],head[u]=idx++;
}
void solve()
{
idx=0;
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++) head[i]=-1,res[i]=0;
for(int i=1;i<n;i++)
{
int k; scanf("%d",&k);
for(int j=1;j<=k;j++)
{
int a; db b; scanf("%d%lf",&a,&b);
addedge(i,a,b);
}
}
res[1]=1.0;
for(int i=1;i<=n;i++)
{
db t=res[i];
for(int u=head[i];u!=-1;u=nex[u])
{
int j=to[u];
res[j]+=t*w[u];
res[i]-=w[u]*t;
}
}
for(int i=1;i<=n;i++) printf("%.10lf ",res[i]);
printf("\n");
}
int main()
{
int tt;
scanf("%d",&tt);
while(tt--) solve();
return 0;
}
H. Hacking Interview Solution
题意
什么给一个multi-dimensional空间,什么学习随机库,反正就是说十几行的废话。最后给你m个数组,每个数组长度为n,问能从中选出几组两两相同的。
思路
感觉阅读理解都算不上,map存一下就行
Code
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6+10;
#define int long long
void solve()
{
int n,m;
cin>>n>>m;
vector<int>a(n+1);
for(int i=1;i<=n;i++)
cin>>a[i];
map<vector<int>,int> cnt;
for(int i=1;i<=m;i++)
{
vector<int> t;
for(int i=1;i<=n;i++)
{
int x; cin>>x;
t.push_back(x);
}
cnt[t]++;
}
int ans=0;
for(auto i : cnt)
{
if(i.second!=1)
ans+=(i.second)*(i.second-1)/2;
}
cout<<ans<<endl;
}
signed main()
{
int tt;
cin>>tt;
while(tt--)
solve();
}
A. Adjacent Swapping
题意
一个由两个相同的字符串构成的字符串,经过数次交换相邻字符的操作后变成目标字符串,给定目标字符串,问最少的操作次数。
思路
先统计一下原串里面字符出现的个数, 然后遍历字符串,如果字符出现的次数不到一半就放在左边那个串,否则放在右边那个串,统计一次答案。此时两个串字符相同但顺序不同,记录一下a串(左边那个)中字符的位置,再把这个位置对应到b串(右边那个里面),这样就变成了一个无序的数组通过相邻两两交换最少需要几次有序,显然求逆序数数量即可。至于这种做法为什么对 我的评价是:
Code
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=2e5+10;
int a[maxn];
struct node
{
int l,r;
ll sum;
}tr[maxn*4];
void pushup(int u)
{
tr[u].sum = tr[u<<1].sum + tr[u<<1|1].sum;
}
void build(int u,int l,int r)
{
if(l==r) tr[u] = {l,r,0};
else
{
tr[u] = {l,r};
int mid = l+r>>1;
build(u<<1,l,mid),build(u<<1|1,mid+1,r);
pushup(u);
}
}
ll query(int u,int l,int r)
{
if(tr[u].l >= l && tr[u].r <= r) return tr[u].sum;
int mid=tr[u].l + tr[u].r >>1;
int res=0;
if(l<=mid) res+=query(u<<1,l,r);
if(r>mid) res+=query(u<<1|1,l,r);
return res;
}
void modify(int u,int pos)
{
if(tr[u].r==pos&&tr[u].l==tr[u].r) tr[u].sum++;
else
{
int mid=tr[u].l+tr[u].r>>1;
if(pos<=mid) modify(u<<1,pos);
else modify(u<<1|1,pos);
pushup(u);
}
}
int main()
{
int n;
map<char,int>cnt,cnt0;
cin>>n;
string s;
cin>>s;
for(int i=0;i<s.size();i++)
cnt[s[i]]++;
string pre,nex; pre = nex = "";
ll ans=0;
for(int i=0;i<s.size();i++)
{
cnt0[s[i]]++;
if(cnt0[s[i]] > cnt[s[i]] / 2)
{
ans += n/2 + int(nex.size()) - i;
nex+=s[i];
}
else
pre+=s[i];
}
vector<int>pos[30];
for(int i=0;i<pre.size();i++)
{
int info = pre[i] - 'a';
pos[info].push_back(i);
}
int p[30]={0};
for(int i=0;i<nex.size();i++)
{
int info = nex[i] - 'a';
a[i] = pos[info][p[info]++];
}
build(1,0,nex.size()-1);
for(int i=0;i<nex.size();i++)
{
ans += query(1,a[i],nex.size()-1);
modify(1,a[i]);
}
cout<<ans<<endl;
}
后记:
蒟蒻就能出这些题了,别的题更是完全不会xD,也找不到题解,所以完结撒花~~
p.s. 这个题目首字母和题号一样还挺有意思的(关注点错)