ACDGIJ
G-Lexicographical Maximum
题意:
给一个数字n,找到0~n中字典序最大的数字
注意:
99和996相比,996的字典序最大;个位数的话就是数字本身
代码:
我的和同学的
#include<bits/stdc++.h>
using namespace std;
int main()
{
bool f=0,to=0;string s;cin>>s;int n=s.size();
for(int i=0;i<n;i++){
if(i==n-1)to=1;
if(s[i]!='9'){f=1;break;}
}
if(n==1)cout<<s;
else if(!f)cout<<s;
else {
for(int i=0;i<n-1;i++)cout<<'9';
if(to)cout<<s[n-1];
}
return 0;
}
#include <bits/stdc++.h>
using namespace std;
string s;
int main ()
{
cin>>s;int length=s.length();
if (length<2)cout<<s;
else{
int cnt=0;
for (int i=1;i<length;++i){cout<<9;if (s[i-1]=='9')++cnt;}
if (cnt==length-1)cout<<s[length-1];
}
}
A-Villages: Landlines
题意:
给电力塔的坐标和有效范围,就需要连接所有塔的电线最小长度
(感觉这道题就是题目理解上困难)
代码:
#include<bits/stdc++.h>
using namespace std;
struct node{
int l,r;
}e[200005];
bool cmp(node &x,node &y){return x.l<y.l;}
int main()
{
int n;cin>>n;int x,r;
for(int i=0;i<n;i++){cin>>x>>r;e[i].l=x-r;e[i].r=x+r;}
sort(e,e+n,cmp);
int ans=0,maxx=e[0].r;
for(int i=1;i<n;i++){
if(e[i].l>maxx)ans+=(e[i].l-maxx);
maxx=max(maxx,e[i].r);
}
cout<<ans<<'\n';
return 0;
}
D-Mocha and Railgun
题意:普通的几何题目
代码:
#include <bits/stdc++.h>
using namespace std;
int T;long long r;long long xq, yq, d;
int main ()
{
cin >> T;
for (int i=1;i<=T;++i){
cin>>r;cin>>xq>>yq>>d;
double dis=sqrt(1.0*xq*xq+1.0*yq*yq);
double shu=sqrt( 1.0*r*r-1.0*(dis-d)*(dis-d) );
double shuyou=sqrt( 1.0*r*r-1.0*(dis+d)*(dis+d) );
double fin=sqrt(1.0*(shu-shuyou)*(shu-shuyou)+4.0*d*d);
double sina=0.5*fin/r;
double a=asin(sina);
cout<<fixed<<setprecision(12)<<2.0*a*r<<endl;
}
}
C-Grab the Seat!
题目:
有n行m列的座位,范围是1≤ x ≤n, 1≤ y ≤m范围里的整数。(0, 1) 到 (0, m) 的线段是屏幕。已有k个人坐在位置上,q次修改,每次修改询问屏幕不会被人遮挡的位置的个数2≤n,m≤2×1e5,1≤k≤2×1e5,1≤q≤200
注意:
k是1~k;eps不能去太大
代码:
#include<bits/stdc++.h>
using namespace std;
#define eps 1e-9
int p[200005]={0},x[200005],y[200005],m1[200005],m2[200005];
int n,m,k,q;
int main()
{
cin>>n>>m>>k>>q;
for(int i=1;i<=k;i++)cin>>x[i]>>y[i];
while(q--){
long long ans=0;
int pi,xi,yi;
cin>>pi>>xi>>yi;
x[pi]=xi,y[pi]=yi;
for(int i=1;i<=m;i++)p[i]=n+1;
for(int i=1;i<=k;i++)p[y[i]]=min(p[y[i]],x[i]);
double kk=0;
for(int i=1;i<=m;i++){
kk=max(kk,1.0*(i-1)/p[i]);
if(kk==0)m1[i]=p[i]-1;
else m1[i]=1.0*(i-1)/kk-eps;
}
kk=0;
for(int i=m;i>0;i--){
kk=min(kk,1.0*(i-m)/p[i]);
if(kk==0) m2[i]=p[i]-1;
else m2[i]=1.0*(i-m)/kk-eps;
ans+=min(m1[i],m2[i]);
}
cout<<ans<<'\n';
}
return 0;
}
J-Serval and Essay
题目:
有一张n个点m条边的无重边无自环的有向图;初始时选择一个点染黑,其余点均为白点;若某个点所有入边的起点均为黑点,则该点可以被染黑;最大化图中黑点数量。
思路:
如果一个点B的入度(A)为1,那么A的出边连接到B的出边连接的点,连接的点的入点为A
用启发式合并,出边的size小的作为儿子,因为要合并边,每个儿子的出边连接的点的from都要变。
注意:
1.如何遍历set
2.如何根据要求建图
3.在merge中如果*it的入度为1,那么记得迭代,因为可能x和y都连着*it,同时y是x的父亲,这样的话如果不迭代就会漏掉
代码:
#include<bits/stdc++.h>
using namespace std;
int fa[200005],sz[200005];
set<int>to[200005],fr[200005];
int find(int x){
return fa[x]==x?fa[x]:fa[x]=find(fa[x]);
}
void merge(int x,int y){
vector<pair<int,int>>vc;
x=find(x),y=find(y);
if(x==y)return;
if(to[x].size()>to[y].size())swap(x,y);
sz[y]+=sz[x];
fa[x]=y;
for(set<int>::iterator it=to[x].begin();it!=to[x].end();++it){
to[y].insert(*it);
fr[*it].erase(x);
fr[*it].insert(y);
if(fr[*it].size()==1)vc.push_back({*it,y});
}
for(int i=0;i<vc.size();i++)merge(vc[i].first,vc[i].second);
}
int main()
{
int T;cin>>T;int cou=1;
while(T--){
int n;cin>>n;
for(int i=1;i<=n;i++){sz[i]=1;fa[i]=i;to[i].clear();fr[i].clear();}
for(int i=1;i<=n;i++){
int x,bi;cin>>x;
for(int j=1;j<=x;j++){
cin>>bi;to[bi].insert(i);fr[i].insert(bi);
}
}
for(int i=1;i<=n;i++){
if(fr[i].size()==1){merge(i,*fr[i].begin());}
}
int ans=0;
for(int i=1;i<=n;++i){ans=max(ans,sz[i]);}
cout<<"Case #"<<cou++<<": "<<ans<<'\n';
}
return 0;
}
I-Chiitoitsu
题意:
手中有13张牌,要做7对子,起手的牌同一个花色最多2张牌,求做成的期望轮次。
思路:
设状态转移方程dp[i][j]表示摸牌次数,i是手中单牌的数量,j是牌山中剩余牌的数量。
1.摸到的牌可以和手上的牌凑对,留下 其概率为:(i * 3) / j (因为手中有i张单牌,那么牌堆中每种单牌都有三张) ②
2.摸到的牌不能和手上的牌凑对,丢掉 其概率为:(j - 3 * i) / j
故 dp[i] [j] = 1 + (3 * i) / j * dp[i - 2][j - 1] + (j - 3 * i) / j * dp[i] [j - 1]
期望=可能性*数量
指增加了一次摸牌次数,如果留下,则加上(3 * i) / j * dp[i - 2][j - 1],若丢弃,则(j - 3 * i) / j * dp[i] [j - 1]
初始化:
只有一张牌没有凑齐了,要么我拿到了,次数加一,要么没拿到,期望加上 (i-3)/3*dp[1][i-1]
故 dp[1][i]=1+(i-3)/3*dp[1][i-1] ;
代码:
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define ll long long
const int mod=1e9+7;
int dp[20][200];
int T;
ll ksm(ll a,ll k,ll mod)
{
ll res = 1;
while(k){
if(k & 1) res = res * a % mod;
k >>= 1;
a = a * a % mod;
}
return res;
}
signed main ()
{
for(int i=3;i<=123;i++){
dp[1][i]=(1+(i-3)*ksm(i,mod-2,mod)%mod*dp[1][i-1])%mod;
}
for(int i=3;i<=13;i+=2){
for(int j=3;j<=123;j++){
dp[i][j]=(1+3*i*ksm(j,mod-2,mod)%mod*dp[i-2][j-1]%mod
+(j-3*i)*ksm(j,mod-2,mod)%mod*dp[i][j-1]%mod)%mod;
}
}
cin >> T;
for (int _= 1; _<= T; _++){
unordered_map<string,int> mp;
string s;cin >> s;
int n = 0;
for(int i = 0;i < s.length();i += 2){
string tmp = "";
tmp += s[i];
tmp += s[i + 1];
mp[tmp] ++;
}
for(int i = 0;i < s.length();i += 2){
string tmp = "";
tmp += s[i];
tmp += s[i + 1];
if(mp[tmp] == 1) n ++;
}
cout << "Case #" <<_<< ": " << dp[n][123] << '\n';
}
}
队友做了B、E,但我还没看