題目來源:https://ac.nowcoder.com/acm/contest/3003#question
這場就比較菜了,差點拿了一血,但是…就差一點點 點點點 實力是六題,因爲有一題數據弱了… 先寫着幾個水題的題解,之後再補(可能明天)
UPD:補完了~
A - 做遊戲
看代碼都能懂
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<stack>
#include<queue>
#include<vector>
#include<set>
#include<map>
#include<string>
#define ls k<<1,l,mid
#define rs k<<1|1,mid+1,r
#define mp(x,y) make_pair(x,y)
#define r(x) read(x)
#define rrr(x,y,z) read(x);read(y);read(z)
#define FOR(i,l,r) for(int i=l;i<=r;i++)
using namespace std;
typedef long long LL;
typedef pair<int,int> pt;
const int N=1e6+5;
const int M=2e3+5;
const int INF=0x7fffffff;
const int mod=1e9+7;
const double eps=1e-8;
const double pi=acos(-1);
LL n,m;
template<class T>
inline void read(T &x)
{
char c; x=1;
while((c=getchar())<'0'||c>'9') if(c=='-') x=-1;
T res=c-'0';
while((c=getchar())>='0'&&c<='9') res=res*10+c-'0';
x*=res;
}
int main()
{
LL a,b,c,x,y,z;
rrr(a,b,c); rrr(x,y,z);
cout<<min(x,c)+min(y,a)+min(z,b)<<endl;
return 0;
}
B - 排數字
統計6 和 1出現的次數 ,設分別爲a b ,那麼答案就是max(min(a-1,b),0)
因爲最簡排法是 616161616 這樣子
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<stack>
#include<queue>
#include<vector>
#include<set>
#include<map>
#include<string>
#define ls k<<1,l,mid
#define rs k<<1|1,mid+1,r
#define mp(x,y) make_pair(x,y)
#define r(x) read(x)
#define rrr(x,y,z) read(x);read(y);read(z)
#define FOR(i,l,r) for(int i=l;i<=r;i++)
using namespace std;
typedef long long LL;
typedef pair<int,int> pt;
const int N=1e6+5;
const int M=2e3+5;
const int INF=0x7fffffff;
const int mod=1e9+7;
const double eps=1e-8;
const double pi=acos(-1);
LL n,m;
char s[N];
template<class T>
inline void read(T &x)
{
char c; x=1;
while((c=getchar())<'0'||c>'9') if(c=='-') x=-1;
T res=c-'0';
while((c=getchar())>='0'&&c<='9') res=res*10+c-'0';
x*=res;
}
int main()
{
r(n);
int cnt1=0,cnt6=0;
scanf("%s",s+1);
FOR(i,1,n){
if(s[i]=='1') cnt1++;
else if(s[i]=='6') cnt6++;
}
cout<<max(0,min(cnt6-1,cnt1))<<endl;
return 0;
}
C - 算概率
設dp[ i ][ j ]爲前i道題做出來j道的概率,可以在複雜度O(n2)內解決
轉移方程爲:dp[i][j]=(dp[i-1][j]*(1-f[i])+dp[i-1][j-1]*f[i]);
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<stack>
#include<queue>
#include<vector>
#include<set>
#include<map>
#include<string>
#define ls k<<1,l,mid
#define rs k<<1|1,mid+1,r
#define mp(x,y) make_pair(x,y)
#define r(x) read(x)
#define rrr(x,y,z) read(x);read(y);read(z)
#define FOR(i,l,r) for(int i=l;i<=r;i++)
using namespace std;
typedef long long LL;
typedef pair<int,int> pt;
const int N=1e6+5;
const int M=2e3+5;
const int INF=0x7fffffff;
const int mod=1e9+7;
const double eps=1e-8;
const double pi=acos(-1);
LL n,m;
LL dp[M][M];
LL f[N];
template<class T>
inline void read(T &x)
{
char c; x=1;
while((c=getchar())<'0'||c>'9') if(c=='-') x=-1;
T res=c-'0';
while((c=getchar())>='0'&&c<='9') res=res*10+c-'0';
x*=res;
}
int main()
{
r(n);
FOR(i,1,n){r(f[i]);}
dp[0][0]=1;
FOR(i,1,n){
dp[i][0]=dp[i-1][0]*(1-f[i]+mod)%mod;
FOR(j,1,i){
dp[i][j]=(dp[i-1][j]*(1-f[i]+mod)%mod+dp[i-1][j-1]*f[i]%mod)%mod;
}
}
FOR(i,0,n) cout<<dp[n][i]<<' ';
cout<<endl;
return 0;
}
D - 數三角
暴力,枚舉三角形的三個點 a b c 通過向量乘積的正負判斷是否有鈍角 即可
但是要注意 三點一線的特判 if(xx*yyy==yy*xxx) return 0;
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<stack>
#include<queue>
#include<vector>
#include<set>
#include<map>
#include<string>
#define ls k<<1,l,mid
#define rs k<<1|1,mid+1,r
#define mp(x,y) make_pair(x,y)
#define r(x) read(x)
#define rrr(x,y,z) read(x);read(y);read(z)
#define FOR(i,l,r) for(int i=l;i<=r;i++)
using namespace std;
typedef long long LL;
typedef pair<int,int> pt;
const int N=1e6+5;
const int M=2e3+5;
const int INF=0x7fffffff;
const int mod=1e9+7;
const double eps=1e-8;
const double pi=acos(-1);
LL n,m;
struct point
{
int x,y;
}f[N];
template<class T>
inline void read(T &x)
{
char c; x=1;
while((c=getchar())<'0'||c>'9') if(c=='-') x=-1;
T res=c-'0';
while((c=getchar())>='0'&&c<='9') res=res*10+c-'0';
x*=res;
}
bool hhh(point a,point b,point c)
{
int xx=b.x-a.x,yy=b.y-a.y;
int xxx=c.x-a.x,yyy=c.y-a.y;
if(xx*yyy==yy*xxx) return 0;
return (xx*xxx+yy*yyy)<0;
}
int main()
{
r(n);
FOR(i,1,n){
scanf("%d%d",&f[i].x,&f[i].y);
}
int ans=0;
FOR(i,1,n){
FOR(j,i+1,n){
FOR(k,j+1,n){
point a=f[i];
point b=f[j];
point c=f[k];
if(hhh(a,b,c)||hhh(b,c,a)||hhh(c,b,a)){
ans++;
}
}
}
}
cout<<ans<<endl;
return 0;
}
E - 做計數
這題也算暴力吧。 首先兩邊平方 得到 i + j + sqrt(ij) = k
我們知道 i j k 都是整數 ,如果ij不能開方出整數 那肯定不行
所以枚舉n以內所有的平方數 1 4 9 …
然後再統計這個平方數的因子即可
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<stack>
#include<queue>
#include<vector>
#include<set>
#include<map>
#include<string>
#define ls k<<1,l,mid
#define rs k<<1|1,mid+1,r
#define mp(x,y) make_pair(x,y)
#define r(x) read(x)
#define rrr(x,y,z) read(x);read(y);read(z)
#define FOR(i,l,r) for(int i=l;i<=r;i++)
using namespace std;
typedef long long LL;
typedef pair<int,int> pt;
const int N=1e6+5;
const int M=2e3+5;
const int INF=0x7fffffff;
const int mod=1e9+7;
const double eps=1e-8;
const double pi=acos(-1);
LL n,m;
template<class T>
inline void read(T &x)
{
char c; x=1;
while((c=getchar())<'0'||c>'9') if(c=='-') x=-1;
T res=c-'0';
while((c=getchar())>='0'&&c<='9') res=res*10+c-'0';
x*=res;
}
int main()
{
r(n);
LL ans=0;
FOR(i,1,n){
int t=sqrt(i);
if(t*t==i){
FOR(j,1,t){
if(i%j==0){
if(j==t) ans++;
else ans+=2;
}
}
}
}
cout<<ans<<endl;
return 0;
}
F - 拿物品
拿的物品a多或者b多對自己都是有好處的,效果相同。
我們以a+b的大小從大到小排序 正着取即可
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<stack>
#include<queue>
#include<vector>
#include<set>
#include<map>
#include<string>
#define ls k<<1,l,mid
#define rs k<<1|1,mid+1,r
#define mp(x,y) make_pair(x,y)
#define r(x) read(x)
#define rrr(x,y,z) read(x);read(y);read(z)
#define FOR(i,l,r) for(int i=l;i<=r;i++)
using namespace std;
typedef long long LL;
typedef pair<int,int> pt;
const int N=1e6+5;
const int M=2e3+5;
const int INF=0x7fffffff;
const int mod=1e9+7;
const double eps=1e-8;
const double pi=acos(-1);
LL n,m;
struct node
{
int a,b,id;
}f[N];
bool cmp(node a,node b)
{
return a.a+a.b>b.a+b.b;
}
template<class T>
inline void read(T &x)
{
char c; x=1;
while((c=getchar())<'0'||c>'9') if(c=='-') x=-1;
T res=c-'0';
while((c=getchar())>='0'&&c<='9') res=res*10+c-'0';
x*=res;
}
int main()
{
r(n);
FOR(i,1,n){
r(f[i].a);
f[i].id=i;
}
FOR(i,1,n) r(f[i].b);
sort(f+1,f+n+1,cmp);
for(int i=1;i<=n;i+=2) cout<<f[i].id<<' ';
cout<<endl;
for(int i=2;i<=n;i+=2) cout<<f[i].id<<' ';
cout<<endl;
return 0;
}
G - 判正誤
這題數據太水,就是 hash ,看後面數據怎麼加強 我的代碼是錯的
你們可以多取幾個模 增加正確率
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<stack>
#include<queue>
#include<vector>
#include<set>
#include<map>
#include<string>
#define ls k<<1,l,mid
#define rs k<<1|1,mid+1,r
#define mp(x,y) make_pair(x,y)
#define r(x) read(x)
#define rrr(x,y,z) read(x);read(y);read(z)
#define FOR(i,l,r) for(int i=l;i<=r;i++)
using namespace std;
typedef long long LL;
typedef pair<int,int> pt;
const int N=1e6+5;
const int M=2e3+5;
const int INF=0x7fffffff;
const int mod=1e9+7;
const double eps=1e-8;
const double pi=acos(-1);
LL n,m;
struct node
{
int a,b,id;
}f[N];
bool cmp(node a,node b)
{
return a.a+a.b>b.a+b.b;
}
template<class T>
inline void read(T &x)
{
char c; x=1;
while((c=getchar())<'0'||c>'9') if(c=='-') x=-1;
T res=c-'0';
while((c=getchar())>='0'&&c<='9') res=res*10+c-'0';
x*=res;
}
LL qpow(LL a,LL p)
{
LL res=1;
while(p){
if(p&1) res=res*a%mod;
a=a*a%mod;
p>>=1;
}
return res;
}
int main()
{
int t;r(t);
while(t--){
LL a,b,c,d,e,f,g;
rrr(a,c,e); rrr(b,d,f); r(g);
if(qpow(a,b)+qpow(c,d)+qpow(e,f)==g) cout<<"Yes\n";
else cout<<"No\n";
}
return 0;
}
H - 施魔法
居然真是DP,dp[ i ]表示的是 取前i個所消耗的最少魔力
轉移方程爲:dp[i]=min(dp[i-1]+f[i]-f[i-1],dp[i-m]+f[i]-f[i-m+1]);
可以這樣想,假如現在已經分了k段了,你要麼把下一個加入第k段,要麼讓這最後k個另成一段,取最小值.
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<stack>
#include<string>
#include<queue>
#include<vector>
#include<set>
#include<map>
#define ls k<<1,l,mid
#define rs k<<1|1,mid+1,r
#define FOR(i,l,r) for(int i=l;i<=r;i++)
#define mp(x,y) make_pair(x,y)
#define pb(x) push_back(x)
#define r(x) read(x)
#define rrr(x,y,z) read(x);read(y);read(z)
using namespace std;
const int N=1e6+5;
const int M=2e3+5;
const int sz=17;
const int INF=0x7fffffff;
const int mod=1e9+7;
const double eps=1e-8;
const double pi=acos(-1);
typedef long long LL;
typedef pair<int,int> pt;
LL n,m;
int f[N];
int dp[N];
template<class T>
inline void read(T &x)
{
char c; x=1;
while((c=getchar())<'0'||c>'9') if(c=='-') x=-1;
T res=c-'0';
while((c=getchar())>='0'&&c<='9') res=res*10+c-'0';
x*=res;
}
int main()
{
r(n); r(m);
FOR(i,1,n) r(f[i]);
sort(f+1,f+n+1);
FOR(i,1,n) dp[i]=f[i]-f[1];
FOR(i,2*m,n){
dp[i]=min(dp[i-1]+f[i]-f[i-1],dp[i-m]+f[i]-f[i-m+1]);
}
cout<<dp[n]<<endl;
return 0;
}
I - 建通道
我的寫法複雜了,因爲一開始題目看錯了 寫成這醜樣了,然後懶得改太多…
如果有相同的元素 那肯定讓他們之間連通 因爲花費爲0 把相同的去重掉就好了。 然後我們肯定是希望lowbit越小越好,我們就從最低爲開始往高位枚舉,設目前到了第k+1位 那如果這個元素&(1<<k) =1 把他放入一個集合A =0 放入一個集合 B 如果這兩個集合都不爲空 ,我們讓這兩個集合的元素互相連通就是讓所以元素連通了。 比如 A中有 a1 a2 ,B中有b1 b2 ,我們讓a1 連 b1 b2 ,a2連b1即可,一共花費即爲 (1<<k)*(n-1)
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<stack>
#include<queue>
#include<vector>
#include<set>
#include<map>
#include<string>
#define ls k<<1,l,mid
#define rs k<<1|1,mid+1,r
#define mp(x,y) make_pair(x,y)
#define r(x) read(x)
#define rrr(x,y,z) read(x);read(y);read(z)
#define FOR(i,l,r) for(int i=l;i<=r;i++)
using namespace std;
typedef long long LL;
typedef pair<int,int> pt;
const int N=1e6+5;
const int M=2e3+5;
const int INF=0x7fffffff;
const int mod=1e9+7;
const double eps=1e-8;
const double pi=acos(-1);
LL n,m;
int f[N];
LL ans;
template<class T>
inline void read(T &x)
{
char c; x=1;
while((c=getchar())<'0'||c>'9') if(c=='-') x=-1;
T res=c-'0';
while((c=getchar())>='0'&&c<='9') res=res*10+c-'0';
x*=res;
}
void hhh(vector<int> v,LL st)
{
vector<int> v1,v2;
bool f1=0,f2=0;
FOR(i,0,v.size()-1){
if(v[i]&st){
f1=1;
v1.push_back(v[i]);
}
else{
f2=1;
v2.push_back(v[i]);
}
}
if(f1&&f2){
LL res=st*(v1.size()+v2.size()-1);
ans=min(ans,res);
return ;
}
if(f1) hhh(v1,st<<1);
if(f2) hhh(v2,st<<1);
}
int main()
{
r(n);
FOR(i,1,n){
r(f[i]);
}
sort(f+1,f+n+1);
n=unique(f+1,f+n+1)-f-1;
ans=0;
if(n==0||n==1) cout<<ans<<endl;
else{
ans=INF;
vector<int> v;
FOR(i,1,n) v.push_back(f[i]);
hhh(v,1);
cout<<ans<<endl;
}
return 0;
}
J - 求函數
這題看出來了是線段樹 但是自己不知道改維護什麼
那就維護k的乘積和那個和就完事~
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<stack>
#include<string>
#include<queue>
#include<vector>
#include<set>
#include<map>
#define ls k<<1,l,mid
#define rs k<<1|1,mid+1,r
#define FOR(i,l,r) for(int i=l;i<=r;i++)
#define mp(x,y) make_pair(x,y)
#define pb(x) push_back(x)
#define r(x) read(x)
#define rrr(x,y,z) read(x);read(y);read(z)
using namespace std;
const int N=1e6+5;
const int M=2e3+5;
const int sz=17;
const int INF=0x7fffffff;
const int mod=1e9+7;
const double eps=1e-8;
const double pi=acos(-1);
typedef long long LL;
typedef pair<LL,LL> pt;
LL n,m;
int kkk[N],ans1[N],ans2[N];
template<class T>
inline void read(T &x)
{
char c; x=1;
while((c=getchar())<'0'||c>'9') if(c=='-') x=-1;
T res=c-'0';
while((c=getchar())>='0'&&c<='9') res=res*10+c-'0';
x*=res;
}
void update(int k,int l,int r,int pos,int kk,int b)
{
if(l==r){
ans1[k]=kk;
ans2[k]=b;
return ;
}
int mid=(l+r)>>1;
if(mid>=pos) update(ls,pos,kk,b);
else update(rs,pos,kk,b);
ans1[k]=1ll*ans1[k<<1]*ans1[k<<1|1]%mod;
ans2[k]=(1ll*ans2[k<<1]*ans1[k<<1|1]+ans2[k<<1|1])%mod;
}
pt merge_pt(pt p1,pt p2)
{
return mp(1ll*p1.first*p2.first%mod,(1ll*p1.second*p2.first%mod+p2.second)%mod);
}
pt query(int k,int l,int r,int x,int y)
{
if(x<=l&&r<=y){
return mp(ans1[k],ans2[k]);
}
int mid=(l+r)>>1;
pt pp=mp(1,0);
if(mid>=x) pp=merge_pt(pp,query(ls,x,y));
if(mid<y) pp=merge_pt(pp,query(rs,x,y));
return pp;
}
int main()
{
r(n); r(m);
FOR(i,1,n) r(kkk[i]);
FOR(i,1,n){
LL b;r(b);
update(1,1,n,i,kkk[i],b);
}
while(m--){
int op;
r(op);
if(op==1){
int i,k,b;
rrr(i,k,b);
update(1,1,n,i,k,b);
}
else{
int l,r;
r(l); r(r);
pt pp=query(1,1,n,l,r);
//cout<<pp.first<<' '<<pp.second<<endl;
cout<<(pp.first+pp.second)%mod<<endl;
}
}
return 0;
}
下次加油哇~爭取多A個題