51 nod 是个好的学习网站,不仅算法分级,而且可以查看别人的优秀代码(过了之后才能查看)。接下来的一些问题就是来自那里。
51 nod 1413 权势二进制(简单数字游戏·贪心)
题目:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1413
一个十进制整数被叫做权势二进制,当他的十进制表示的时候只由0或1组成。例如0,1,101,110011都是权势二进制而2,12,900不是。
当给定一个n的时候,计算一下最少要多少个权势二进制相加才能得到n。
单组测试数据。
第一行给出一个整数n (1<=n<=1,000,000)
输出答案占一行。
9
9
import java.util.*; public class Main { public static void main(String[] args) { Scanner sc=new Scanner(System.in); String str; int [] m=new int [7]; while(sc.hasNext()){ str=sc.next(); Arrays.fill(m,0); int length=str.length(); for(int i=0;i<length;i++){ m[i]=str.charAt(i)-48; } int ans=0; for(int i=0;i<length;i++){ if(m[i]>0){ ans+=m[i]; for(int j=i+1;j<length;j++){ m[j]-=m[i]; } } } System.out.println(ans); } } }
51nod 1381 硬币游戏(简单概率)
http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1381第一行给出一个整数T,表示有T组数据(1<=T<=10000)。
第2行到T+1,每行给出一个整数R。(0< R <= 10,000,000,000)
对于每一个数据,在一行中输出答案的整数部分即可。
1
1
2
2 2 6
1 1 0
50000 50000 1000000000
8
0
1562562500625000000
分析:
继续设想:当i=3呢,那么(m-1+1)-->(m-3+1);所以设q=min(n,k/2-1),j=k/2-i。一个字符串,只包含01,长度不超过1000000。
一行一个整数,最长的0与1的个数相等的子串的长度。
1011
2
#include <iostream> //一定要让计算数据变化 #include <cstdio> #include <cstring> #include <map> using namespace std; const int maxn=1e6+5; char str[maxn]; int p[maxn]; int main() { //freopen("cin.txt","r",stdin); while(~scanf("%s",str+1)){ int length=strlen(str+1); int ans=0; memset(p,0,sizeof(p)); map<int,int> mp; //默认0 for(int i=1;i<=length;i++){ if(str[i]=='1') p[i]=p[i-1]+1; else p[i]=p[i-1]-1; if(mp[p[i]]==0&&p[i]!=0)mp[p[i]]=i; if(i!=1){ ans=max(ans,i-mp[p[i]]); //cout<<i<<" "<<p[i]<<" "<<mp[p[i]]<<endl; } } printf("%d\n",ans); } return 0; }
#define LEN 1000001 int v[LEN*2]; char s[LEN]; int main() { int len,dis=0,ret=0; scanf("%s",s); len=strlen(s); memset(v,-1,sizeof(v)); for(int i=0;i<len;i++) { if(s[i]=='1') dis++; else dis--; if(v[dis+LEN]==-1&&dis!=0) { v[dis+LEN]=i; } else { if(ret<i-v[dis+LEN]) ret=i-v[dis+LEN]; } } printf("%d\n",ret); }
正当Noder惊魂未定的时候,走来一个美女,要求和他一起玩个数学游戏。美女提议:“让我们各自亮出硬币的一面,或正或反。如果我们都是正面,那么我给你A元,如果我们都是反面,我给你B元(A + B为偶数)。剩下的情况你给我(A + B) / 2元就可以了。
Noder知道这个游戏他多半要输,可他并不在乎,他只想让自己输的慢一点。
那么你来帮美女计算一下,她选择出正面的概率应该是多少(以最简分数形式输出)?
当Noder输光了钱后从草地上醒来,吉普赛姑娘已经不见了,只留下了这样一张塔罗牌,上面印有那个美女的照片。
关于样例的解释:
美 女采取了(3/8,5/8)这个方案,不论Noder采用什么方案,都是不能改变局面的。如果全部出正面,每次的期望收益是 (3+3+3-2-2-2-2-2)/8=-1/8元;如果全部出反面,每次的期望收益也是(-2-2-2+1+1+1+1+1)/8=-1/8元。而任 何策略无非只是上面两种策略的线性组合,所以期望还是-1/8元。
第1行:一个数T,表示后面用作输入测试的数的数量(1 <= T <= 20)。
第2 - T + 1行:每行2个数A, B中间用空格分隔。(1 <= A, B <= 10^9,且A + B为偶数)。
输出共T行,对应美女选择正面的概率,以最简分数形式输出,具体请参看输出样例。
2
3 1
1 3
3/8
5/8
依据样例分析,全部选定正面和反面的结果应该是一样的,最后一定是女性胜利。那么设女性选择正面的概率是x,正面的A元-->a,反面的B元-->b,
有这样的等式:
import java.util.*; public class Main { static long gcd(long a,long b){ return b>0?gcd(b,a%b):a; } public static void main(String[] args) { Scanner sc=new Scanner (System.in); long t=sc.nextInt(),a,b; for(int k=0;k<t;k++){ a=sc.nextInt(); b=sc.nextInt(); long q1=a+3*b; long q2=4*(a+b); long r=gcd(q1,q2); //System.out.println(q1+" "+q2+" "+r); q1=q1/r; q2=q2/r; System.out.println(q1+"/"+q2); } } }
51nod 1433 0和5(整除的规律)
小K手中有n张牌,每张牌上有一个一位数的数,这个字数不是0就是5。小K从这些牌在抽出任意张(不能抽0张),排成一行这样就组成了一个数。使得这个数尽可能大,而且可以被90整除。
注意:
1.这个数没有前导0,
2.小K不需要使用所有的牌。
每个测试数据输入共2行。
第一行给出一个n,表示n张牌。(1<=n<=1000)
第二行给出n个整数a[0],a[1],a[2],…,a[n-1] (a[i]是0或5 ) 表示牌上的数字。
共一行,表示由所给牌组成的可以被90整除的最大的数,如果没有答案则输出”-1”(没有引号)
4
5 0 5 0
0
import java.util.*; public class Main { static int min(int a,int b){ return a<b?a:b; } public static void main(String[] args) { Scanner sc=new Scanner (System.in); int n,a,five,zero; while(sc.hasNext()){ n=sc.nextInt(); five=0; for(int i=0;i<n;i++){ a=sc.nextInt(); if(a==5) five++; } zero=n-five; int k=five/9; k=min(k,zero); if(k>0){ for(int i=0;i<k;i++){ for(int j=0;j<9;j++) System.out.printf("5"); } //for(int i=0;i<k;i++) for(int i=0;i<zero;i++) System.out.printf("0"); System.out.println(); } else { if(zero==0){ System.out.println(-1); continue; } System.out.println(0); } } } }