额,貌似都是暴力,除了油菜花那个用了数据结构。考验细心与编程能力。挺不错的 。
1001,搬砖
题意:给你一个数字,把数字分为2半,代价是分开后二者的差值。要求最后全部是1。
解法:用dfs(n):表示把n分为2半需要的代价。
//#define CF
#ifndef CF
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<string>
#include<iostream>
#include<set>
#include<vector>
#else
#include<bits/stdc++.h>
#endif // CF
using namespace std;
#define LL long long
#define pb push_back
#define X first
#define Y second
#define cl(a,b) memset(a,b,sizeof(a))
typedef pair<long long ,long long > P;
const int maxn=10000005;
const LL inf=1LL<<50;
const LL mod=1e9+7;
int dfs(int n){
if(n==1)return 0;
if(n==2)return 0;
if(n&1)return dfs(n/2+1)+dfs(n/2)+1;
else return dfs(n/2)+dfs(n/2);
}
int main() {
int T;scanf("%d",&T);
while(T--){
int n;scanf("%d",&n);
printf("%d\n",dfs(n));
}
return 0;
}
1002 投币洗衣机
题意:告诉衣服数量在[a,b)–>2,[b,c)–>3,[c,+oo)–>4.然后每天有衣服的数量,一旦衣服数量达到区间就计算。
解答:用一个计数器,累计衣服的数量
//#define CF
#ifndef CF
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<string>
#include<iostream>
#include<set>
#include<vector>
#else
#include<bits/stdc++.h>
#endif // CF
using namespace std;
#define LL long long
#define pb push_back
#define X first
#define Y second
#define cl(a,b) memset(a,b,sizeof(a))
typedef pair<long long ,long long > P;
const int maxn=10000005;
const LL inf=1LL<<50;
const LL mod=1e9+7;
int main() {
int n,a,b,c;
while(~scanf("%d%d%d%d",&n,&a,&b,&c)){
int sum=0;
int x_sum=0;
for(int i=0;i<n;i++){
int x;scanf("%d",&x);
x_sum+=x;
if(x_sum>=a&&x_sum<b){
sum+=2;x_sum=0;
}
else if(x_sum>=b&&x_sum<c){
sum+=3;x_sum=0;
}
else if(x_sum>=c){
sum+=4;x_sum=0;
}
}
printf("%d\n",sum);
}
return 0;
}
1003 玩骰子
题意:给你A,B二人的筛子,情况,按照题目要求的比较规则,如果A再扔一次筛子的获胜概率。
解法:实际上是掷某一个骰子后,某个筛子能带来的最大胜率。写一个判断函数,暴力枚举
//#define CF
#ifndef CF
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<string>
#include<iostream>
#include<set>
#include<vector>
#else
#include<bits/stdc++.h>
#endif // CF
using namespace std;
#define LL long long
#define pb push_back
#define X first
#define Y second
#define cl(a,b) memset(a,b,sizeof(a))
typedef pair<long long ,long long > P;
const int maxn=50505*2;
const LL inf=1LL<<50;
const LL mod=1e9+7;
bool isThree(int b[]){
return b[0]==b[1]&&b[1]==b[2];
}
bool isTwo(int b[]){
return b[0]==b[1]||b[1]==b[2];
}
int get_(int a[]){
if(a[0]==a[1])return a[2];
if(a[1]==a[2])return a[0];
}
int getdb(int a[]){
if(a[0]==a[1])return a[0];
if(a[1]==a[2])return a[1];
}
bool pan(int *a,int *b){
if(isThree(a)){
if(isThree(b)&&b[0]>=a[0])return 0;
return 1;
}
else if(isTwo(a)){
if(isThree(b))return 0;
else if(isTwo(b)){
if(getdb(a)>getdb(b))return 1;
else if(getdb(a)==getdb(b)&&get_(a)>get_(b))return 1;
else return 0;
}
else return 1;
}
else {
if(isThree(b))return 0;
else if(isTwo(b))return 0;
else {
for(int i=2;i>=0;i--){
if(a[i]==b[i])continue;
return a[i]>b[i];
}
return 0;
}
}
}
void Copy(int* a,int* b){
for(int i=0;i<3;i++)a[i]=b[i];
}
int aa[3];
int a[3],b[3];
int main() {
int T;scanf("%d",&T);
while(T--){
for(int i=0;i<3;i++){
cin>>a[i];aa[i]=a[i];
}
sort(a,a+3);
for(int i=0;i<3;i++){
cin>>b[i];
}
sort(b,b+3);
if(pan(a,b)){
printf("1.000\n");continue;
}
double ans=0;
for(int i=0;i<3;i++){
double tmp=0;
for(int j=1;j<=6;j++){
Copy(a,aa);
a[i]=j;
sort(a,a+3);
if(pan(a,b))tmp+=1.0/6.0;
}
ans=max(ans,tmp);
}
printf("%.3lf\n",ans);
}
return 0;
}
1004 质方数
题意:给你一个数,找到一个数是质数,且平方最接近给出的数n
解法:二分查找,先生成质方数的表,二分查找。
//#define CF
#ifndef CF
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<string>
#include<iostream>
#include<set>
#include<vector>
#else
#include<bits/stdc++.h>
#endif // CF
using namespace std;
#define LL long long
#define pb push_back
#define X first
#define Y second
#define cl(a,b) memset(a,b,sizeof(a))
typedef pair<long long ,long long > P;
const int maxn=10605;
const LL inf=1LL<<50;
const LL mod=1e9+7;
bool p[maxn];
LL st[maxn];
int init(){
p[0]=p[1]=1;
for(int i=2;i<maxn;i++)if(!p[i]){
for(int j=i+i;j<maxn;j+=i){
p[j]=1;
}
}
int num=0;
//for(int i=1;i<10;i++)if(!p[i])printf("%d\n",i);
for(int i=1;i<maxn;i++)if(!p[i]){
st[num++]=(LL)i*i;
}
return num;
}
int main() {
int N=init();
//for(int i=0;i<10;i++)printf("%lld\n",st[i]);
int T;scanf("%d",&T);
while(T--){
LL n;scanf("%lld",&n);
int x,y;
x=lower_bound(st,st+N,n)-st;
if(st[x]==n)printf("%lld\n",st[x]);
else {
int xx=x;
if(xx>1)xx--;
int yy=x;
if(n-st[xx]<st[yy]-n){
printf("%lld\n",st[xx]);
}
else {
printf("%lld\n",st[yy]);
}
}
}
return 0;
}
1005 ACM组队安排
题意:给你一个数n,然后可以分为1-3,人组队。问分法,不能重复。
解法:递推,ans[n]:n个人的组合数,考虑第n个人,单独的话,那么其他的是ans[n-1],如果,在n-1人选择一个和n组合,那么有C(n-1,1)选法,那么还剩ans[n-2],就是C(n-1,1) * ans[n-2],若果选择2个组队,那么就是C(n-1,2),对应ans[n-3],总计C(n-1,2) * ans[n-3],所以总计:ans[n]=ans[n-1]+(n-1) * ans[n-2]+(n-1) * (n-2)/2 * ans[n-3]
//#define CF
#ifndef CF
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<string>
#include<iostream>
#include<set>
#include<vector>
#else
#include<bits/stdc++.h>
#endif // CF
using namespace std;
#define LL long long
#define pb push_back
#define X first
#define Y second
#define cl(a,b) memset(a,b,sizeof(a))
typedef pair<long long ,long long > P;
const int maxn=50505*2;
const LL inf=1LL<<50;
const LL mod=1e9+7;
LL ans[21];
void init(){
ans[1]=1;ans[2]=2;ans[3]=5;
for(int i=4;i<=20;i++){
ans[i]=ans[i-1]+(i-1)*ans[i-2]+(i-1)*(i-2)/2*ans[i-3];
}
}
int main() {
int n;
init();
while(~scanf("%d",&n)&&n!=0) {
printf("%lld\n",ans[n]);
}
return 0;
}
1006 逆袭指数
题意:找出一个数的最大连续因子积
解答:暴力,素数直接判断,其他的暴力计算
//#define CF
#ifndef CF
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<string>
#include<iostream>
#include<set>
#include<vector>
#else
#include<bits/stdc++.h>
#endif // CF
using namespace std;
#define LL long long
#define pb push_back
#define X first
#define Y second
#define cl(a,b) memset(a,b,sizeof(a))
typedef pair<long long ,long long > P;
const int maxn=5050;
const LL inf=1LL<<50;
const LL mod=1e9+7;
bool isp(LL n){
if(n==1||n==0)return true;
if(n==2)return false;
for(int i=2;i*i<=n;i++)if(n%i==0)return false;
return true;
}
LL f(int st,int len){
LL fac=1;
int i=0;while(i<len)fac*=st++,i++;
return fac;
}
int main(){
LL n;
while(~scanf("%lld",&n)){
if(isp(n)){
printf("1\n%d\n",n);continue;
}
if(n==2){
printf("1\n2\n");continue;
}
LL myst=0,len=0;
for(int st=2;st*st<=n;st++){
for(int j=1;;j++){
LL num=f(st,j);
if(num>n)break;
if(n%num==0){
if(j>len){
len=j;
myst=st;
}
}
}
}
printf("%lld\n",len);
for(int i=myst;i<myst+len;i++){
if(i==myst)printf("%d",i);
else printf("*%d",i);
}
puts("");
}
return 0;
}
1007 油菜花王国
题意:给你一个关系图,以及每个点的权重,如果权重时斐波那契数,那么贡献是1.
解答:并查集或者连通图。
//#define CF
#ifndef CF
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<string>
#include<iostream>
#include<set>
#include<vector>
#else
#include<bits/stdc++.h>
#endif // CF
using namespace std;
#define LL long long
#define pb push_back
#define X first
#define Y second
#define cl(a,b) memset(a,b,sizeof(a))
typedef pair<long long ,long long > P;
const int maxn=50505*2;
const LL inf=1LL<<50;
const LL mod=1e9+7;
LL a[maxn];
vector<int> G[maxn];
int dfn[maxn],low[maxn],s[maxn];
int belong[maxn];
bool ins[maxn];
int cnt,num,top;
int my[maxn];
void dfs(int u){
dfn[u]=low[u]=++num;
s[++top]=u;
ins[u]=true;
int N=G[u].size();
for(int i=0;i<N;i++){
int v=G[u][i];
if(!dfn[v]){
dfs(v);
low[u]=min(low[u],low[v]);
}
else if(ins[v]&&dfn[v]<low[u]){
low[u]=dfn[v];
}
}
if(low[u]==dfn[u]){
cnt++;
int v;
do{
v=s[top--];
ins[v]=false;
belong[v]=cnt;
my[cnt]++;
}while(v!=u);
}
}
void Tarjan(int n){
cnt=num=top=0;
cl(dfn,0);
cl(ins,false);
cl(my,0);
cl(belong,0);
for(int i=1;i<=n;i++)if(!dfn[i]){
dfs(i);
}
}
LL fib[maxn];
void init(){
fib[1]=fib[2]=1;
for(int i=3;i<47;i++){
fib[i]=fib[i-1]+fib[i-2];
//printf("%lld\n",fib[i]);
if(fib[i]>1000000001LL)break;
}
}
bool used[1005][1005];
int main() {
int n,m;
init();
while(~scanf("%d%d",&n,&m)){
for(int i=0;i<maxn;i++)G[i].clear();
cl(used,false);
for(int i=1;i<=n;i++){
scanf("%lld",&a[i]);
}
for(int i=0;i<m;i++){
int u,v;
scanf("%d%d",&u,&v);
if(u==v)continue;
if(used[u][v]||used[v][u])continue;
used[u][v]=used[v][u]=true;
G[u].pb(v);
G[v].pb(u);
}
Tarjan(n);
int mx=0,id=0;
for(int i=1;i<=cnt;i++){
if(mx<my[i]){
mx=my[i];
id=i;
}
}
LL ans=0;
for(int i=1;i<=n;i++){
if(belong[i]==id){
for(int j=1;j<47;j++){
if(fib[j]==a[i]){
//cout<<i<<endl;
ans+=1;break;
}
}
}
}
printf("%lld\n",ans);
}
return 0;
}
1008 游乐场
题意:去玩,有几个地方必须去,每个地方有花费,然后如果钱剩余的多,那么可以去玩别的 。想尽可能玩的多。
解法:先去掉必须去的,然后排序,贪心。
//#define CF
#ifndef CF
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<string>
#include<iostream>
#include<set>
#include<vector>
#else
#include<bits/stdc++.h>
#endif // CF
using namespace std;
#define LL long long
#define pb push_back
#define X first
#define Y second
#define cl(a,b) memset(a,b,sizeof(a))
typedef pair<long long ,long long > P;
const int maxn=10605;
const LL inf=1LL<<50;
const LL mod=1e9+7;
struct node{
LL val;int id;
bool operator<(const node& t) const {
return val<t.val;
}
}x[maxn];
bool vis[maxn];
int main() {
int T;scanf("%d",&T);
while(T--){
int n,m;LL k;
scanf("%d%d%lld",&n,&m,&k);
for(int i=1;i<=n;i++){
scanf("%lld",&x[i].val);
x[i].id=i;
}
cl(vis,false);
LL p_sum=0;
for(int i=1;i<=m;i++){
int p;
scanf("%d",&p);
p_sum+=x[p].val;
vis[p]=true;
}
if(p_sum>k){
printf("-1\n");continue;
}
k-=p_sum;
sort(x+1,x+n+1);
//for(int i=1;i<=n;i++)printf("%lld\n",x[i]);
int ans=m;
for(int i=1;i<=n;i++)if(!vis[x[i].id]){
if(k>=x[i].val){
ans++;
k-=x[i].val;
}
else break;
}
printf("%d\n",ans);
}
return 0;
}