2018牛客國慶集訓派對 day3
阿新 • • 發佈:2018-12-13
D:很水的簽到題。
#include<bits/stdc++.h> using namespace std; int n,m; double a[1050]; int b[1050]; bool cmp(int x,int y) { return x>y; } int main() { int t; cin>>t; while(t--) { cin>>n>>m; int cnt=0; for(int i=0; i<n; i++) { cin>>a[i]>>b[i]; if(b[i]) cnt++; } sort(a,a+n,cmp); double ans=0; cnt=min(cnt,m); for(int i=0;i<cnt;i++) { ans+=a[i]/2; } for(int i=cnt;i<n;i++) ans+=a[i]; printf("%.1f\n",ans); } }
H:題意不是很清楚,但是發現和樹的結構沒有關係,只要考慮如何把樹上的結點分成幾部分就可以了,推完發現是個組合數取模,我們預處理階乘,用乘法逆元即可。
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int maxn=1e5+5; const int mod=1e9+7; ll fac[maxn]; void init_fac() { fac[0]=fac[1]=1; for(int i=2;i<maxn;i++) fac[i]=i*fac[i-1]%mod; } ll quickpow(ll a,ll n) { ll ret=1; while(n) { if(n&1) ret=ret*a%mod; a=a*a%mod; n>>=1; } return ret; } ll C(ll a,ll b) { return fac[a]*quickpow(fac[b],mod-2)%mod*quickpow(fac[a-b],mod-2)%mod; } int main() { int t; scanf("%d",&t); init_fac(); while(t--) { int n,m; scanf("%d %d",&n,&m); for(int i=1;i<n;i++) { int x,y; scanf("%d %d",&x,&y); } ll ans=C(n-1,m-1)*fac[m]%mod; printf("%lld\n",ans); } }
A:問馬走日最少幾步,原題,可以考慮把終點放在第一象限角平分線的上方,通過找規律可以得出答案。
#include<bits/stdc++.h> using namespace std; int main() { int x, y, ans; int t; cin>>t; while(t--) { cin>>x>>y; x=abs(x); y=abs(y); if(x>y)swap(x, y); if(y==x*2) { printf("%d\n", (x+y)/3); continue; } if(y<=2*x) { if(x==1&&y==1) ans = 2; else if(x==2&&y==2) ans = 4; else ans = (x+y)/3+(x+y)%3; } else { ans=x; int c=(y-2*x)%4; ans+=c; ans+=(y-2*x-c)/2; if(y==1&&x==0) ans=3; } printf("%d\n",ans); } return 0; }
I:判斷是否二分圖
有奇環一定不是二分圖,否則一定是二分圖。
最開始我考慮bfs染色,但是發現無法列印環,於是我記錄了成環的2個結點又用了一次dfs搜路徑,然後爆記憶體了。
所以要列印路徑,直接寫dfs即可,但是記住加一個記號判斷是否形成奇環,有奇環層層遞迴退出程式,否則dfs還會一直搜下去,程式會T。
#include<bits/stdc++.h>
using namespace std;
int const maxn=3e5+5;
vector<int>G[maxn];
int color[maxn];
int pre[maxn];
bool iscircle;
bool dfs(int v,int c)
{
color[v]=c;
for(int i=0; i<G[v].size(); i++)
{
if(color[v]==color[G[v][i]])
{
iscircle=true;
int cnt=0;
int tem=v;
int tmp=G[v][i];
while(v!=tmp)
{
cnt++;
v=pre[v];
}
printf("%d\n",cnt+1);
while(tem!=tmp)
{
printf("%d ",tem);
tem=pre[tem];
}
printf("%d ",tem);
return false;
}
if(color[G[v][i]]==0)
{
pre[G[v][i]]=v;
dfs(G[v][i],-c);
if(iscircle) return false; //這裡要下個標記不然會T
}
}
return true;
}
int main()
{
int n,m;
scanf("%d %d",&n,&m);
for(int i=1; i<=m; i++)
{
int u,v;
scanf("%d %d",&u,&v);
G[u].push_back(v);
G[v].push_back(u);
}
memset(color,0,sizeof(color));
iscircle=false;
if(dfs(1,1))
{
printf("0\n");
for(int i=1; i<=n; i++)
{
if(color[i]==1)
printf("1 ");
else printf("0 ");
}
}
}
未完待續......