SlideShare a Scribd company logo
1 of 13
+
AOJ0030
Sum of Integers
ICPC AOJ Meeting 2014/7/21
+
Problem
0 から 9 の数字から異なる n 個の数を取り出して合計が s とな
る組み合わせの数を出力するプログラムを作成してください。n
個の数はおのおの 0 から 9 までとし、1つの組み合わせに同じ
数字は使えません。たとえば、n が 3 で s が6 のとき、3 個の数
字の合計が 6 になる組み合わせは、
1 + 2 + 3 = 6
0 + 1 + 5 = 6
0 + 2 + 4 = 6
の三通りとなります。
+
SourceCode
http://ideone.com/d4Vo0B
+
Solution
 まず、10個の要素からn個選択される場合のパターンを列挙す
る。パターンはビット列で表現される。例えば、0~9から3個
378を選択する場合は0001000110と表現される。
 上記の全選択パターンを数字の合計に応じて振り分ける。例え
ば上記の例の場合、3+7+8=18で合計が18のパターンのリスト
に振り分けられる。
 合計の数sに対応したパターンのリストを取得、リストの要素
数を表示する。
+
Main
public class Main {
public static void main(String[] args){
BinaryPool binaryPool = new BinaryPool(10);
Scanner sc = new Scanner(System.in);
while(sc.hasNext()){
String[] strs = sc.nextLine().split(" ");
int n = Integer.parseInt(strs[0]);
int s = Integer.parseInt(strs[1]);
if(n==0&&s==0){
break;
}
System.out.println(new Execution(binaryPool,n).getPattern(s));
}
}
}
入力文字列を空白でsplit、
intに変換。s,nが共に0の時
ループを抜ける。
+
Execution
class Execution{
private ArrayList<String> binaryData;
private HashMap<Integer,ArrayList<String>> result;
public Execution(BinaryPool binaryPool,int n){
binaryData=binaryPool.getFilteredData(n);
result=new HashMap<Integer, ArrayList<String>>();
analysis();
}
private void analysis(){
for(String s:binaryData){
if(result.containsKey(listSum(decoder(s)))){
result.get(listSum(decoder(s))).add(makeFormula(decoder(s)));
}else{
ArrayList<String> tmp = new ArrayList<String>();
tmp.add(s);
result.put(listSum(decoder(s)),tmp);
}
}
}
生成したビット列を合計値
で振り分ける
+ private String makeFormula(ArrayList<Integer> aList){
StringBuilder sb = new StringBuilder();
for(int i=0;i<aList.size();i++){
if(i==aList.size()-1){
sb.append(Integer.toString(aList.get(i)));
}else{
sb.append(Integer.toString(aList.get(i))+"+");
}
}
return sb.toString();
}
private ArrayList<Integer> decoder(String str){
ArrayList<Integer> tmp = new ArrayList<Integer>();
for(int i=0;i<str.length();i++){
if(str.charAt(i)=='1'){
tmp.add(i);
}
}
return tmp;
}
リストを数式に変換する
4,7,9 -> 4+7+9
ビット列を数字のリストに変換する
0011000100 -> 2,3,7
private int listSum(ArrayList<Integer> aList){
int s=0;
for(int n:aList){
s+=n;
}
return s;
}
public int getPattern(int sum){
int s;
try{
s=result.get(sum).size();
}catch (NullPointerException e){
s=0;
}
return s;
}
入力sに対応するリストを取得し、
そのリストの長さをreturnする。
リストがnullの場合、入力された和
になるパターンは存在しないとい
うことなので0をreturnする。
引数に与えられたリストの
和をreturnする
+
BinaryPool
private int target;
private String[] binaryData;
public BinaryPool(int target){
this.target=target;
binaryData = new String[(int)Math.pow(2,target)];
calculation();
}
private void calculation(){
for(int i=0;i<binaryData.length;i++){
binaryData[i] = complementBin(Integer.toBinaryString(i));
}
}
private String complementBin(String str){
for(int i=str.length();i<target;i++){
str="0"+str;
}
return str;
}
コンストラクタ
データ格納領域を確保する。
10bitの2進数全パターンは
2^10=1024通りあるのでその個
数分String配列を確保する。
0~1023を2進数に変換し、配
列に格納する。
生成した2進数を10bitに揃え
る。例えば63=111111を
0000111111に変換する。
public String[] getData(){
return binaryData;
}
public ArrayList<String> getFilteredData(int t) {
ArrayList<String> tmp = new ArrayList<String>();
for (int i = 0; i < binaryData.length; i++) {
if (countBit(binaryData[i]) == t) {
tmp.add(binaryData[i]);
}
}
return tmp;
}
private int countBit(String str){
int c=0;
for(int i=0;i<str.length();i++){
if(str.charAt(i)=='1'){
c++;
}
}
return c;
}
全パターンデータのgetter
指定した個数分ビットが立って
いるものをフィルタしてパター
ンデータ取得
何個ビットが立っているか数える
+
Ruby
 $stdin.read.split(?n).map{|m|m.split("
")}.select{|i|i[0].to_i!=0&&i[1].to_i!=0}.each{|e|p
(0..9).to_a.combination(e[0].to_i).select{|i|i.inject(:+)==e[1].to_i}.
length}
 140文字以内にしてTweetしたかったけど出来なかった・・・。
+
短くしてみた
import java.util.Scanner;
public class Main{
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
while(sc.hasNext()){
String[] strs = sc.nextLine().split(" ");
int n = Integer.parseInt(strs[0]);
int s = Integer.parseInt(strs[1]);
if(n==0&&s==0)
break;
System.out.println(calculation(n,s));
}
}
private static int calculation(int n,int s){
int c=0;
for(int i=0;i<(int)Math.pow(2,10);i++)
if(countBit(complementBin(Integer.toBinaryString(i)))==n&&getSum(complementBin(Integer.toBinaryString(i)))
==s)
c++;
return c;
}
private static String complementBin(String str){
for(int i=str.length();i<10;i++)
str="0"+str;
return str;
}
private static int countBit(String str){
int c=0;
for(int i=0;i<str.length();i++)
if(str.charAt(i)=='1')
c++;
return c;
}
private static int getSum(String str){
int s=0;
for(int i=0;i<str.length();i++)
if(str.charAt(i)=='1')
s+=i;
return s;
}
}
+
C
#include<stdio.h>
#include<math.h>
#define BIT 10
int bitArray[BIT];
void print(){
for(int i=0;i<BIT;i++){
printf("%d",bitArray[i]);
}
printf("n");
}
int countBit(){
int c=0;
for(int i=0;i<BIT;i++)
if(bitArray[i])
c++;
return c;
}
int getSum(){
int s=0;
for(int i=0;i<BIT;i++)
if(bitArray[i])
s+=i;
return s;
}
void genBit(int n){
for(int i=0;i<BIT;i++){
bitArray[BIT-i-1]=n%2;
n=n/2;
}
}
int calculation(int n,int s){
int c=0;
for(int i=0;i<(int)pow(2,BIT);i++){
genBit(i);
//print();
if(countBit()==n&&getSum()==s)
c++;
}
return c;
}
int main(void){
while(1){
int n,s;
scanf("%d %d",&n,&s);
if(n==0&&s==0){
break;
}
printf("%dn",calculation(n,s));
}
return 0;
}

More Related Content

Viewers also liked (19)

шевченко
шевченкошевченко
шевченко
 
Shringa brochure
Shringa brochureShringa brochure
Shringa brochure
 
змагання зі спортивної гімнастики
змагання зі спортивної гімнастикизмагання зі спортивної гімнастики
змагання зі спортивної гімнастики
 
Cb Utpl
Cb UtplCb Utpl
Cb Utpl
 
Redes sociais
Redes sociaisRedes sociais
Redes sociais
 
CMP PX2K-32 Barrier Glands Exd Flameproof (ATEX) Cable Glands
CMP PX2K-32 Barrier Glands Exd Flameproof (ATEX) Cable GlandsCMP PX2K-32 Barrier Glands Exd Flameproof (ATEX) Cable Glands
CMP PX2K-32 Barrier Glands Exd Flameproof (ATEX) Cable Glands
 
Barra de direcciones ayuda de google chrome
Barra de direcciones   ayuda de google chromeBarra de direcciones   ayuda de google chrome
Barra de direcciones ayuda de google chrome
 
Devika 1
Devika 1Devika 1
Devika 1
 
Trabajo de biomasa
Trabajo de biomasaTrabajo de biomasa
Trabajo de biomasa
 
Principios de la energía solar
Principios de la energía solarPrincipios de la energía solar
Principios de la energía solar
 
Deber n1 deontooo
Deber n1 deontoooDeber n1 deontooo
Deber n1 deontooo
 
Deber n3
Deber n3Deber n3
Deber n3
 
Power quality management
Power quality managementPower quality management
Power quality management
 
Prvision mercredi 14 janvier 2014
Prvision mercredi 14 janvier 2014Prvision mercredi 14 janvier 2014
Prvision mercredi 14 janvier 2014
 
презентация шевченко
презентация шевченко презентация шевченко
презентация шевченко
 
Presentacin2
Presentacin2Presentacin2
Presentacin2
 
Dịch vụ quảng cáo facebook
Dịch vụ quảng cáo facebook Dịch vụ quảng cáo facebook
Dịch vụ quảng cáo facebook
 
Informatica
InformaticaInformatica
Informatica
 
Jackson Pollock
Jackson PollockJackson Pollock
Jackson Pollock
 

More from nullzine

第二回ミーティングスライド
第二回ミーティングスライド第二回ミーティングスライド
第二回ミーティングスライドnullzine
 

More from nullzine (13)

Meeting19
Meeting19Meeting19
Meeting19
 
Meeting18
Meeting18Meeting18
Meeting18
 
Meeting13
Meeting13Meeting13
Meeting13
 
Meeting12
Meeting12Meeting12
Meeting12
 
Meeting11
Meeting11Meeting11
Meeting11
 
Meeting10
Meeting10Meeting10
Meeting10
 
Meeting9
Meeting9Meeting9
Meeting9
 
Meeting8
Meeting8Meeting8
Meeting8
 
Meeting7
Meeting7Meeting7
Meeting7
 
Meeting6
Meeting6Meeting6
Meeting6
 
Meeting5
Meeting5Meeting5
Meeting5
 
Meeting4
Meeting4Meeting4
Meeting4
 
第二回ミーティングスライド
第二回ミーティングスライド第二回ミーティングスライド
第二回ミーティングスライド
 

Meeting1

  • 1. + AOJ0030 Sum of Integers ICPC AOJ Meeting 2014/7/21
  • 2. + Problem 0 から 9 の数字から異なる n 個の数を取り出して合計が s とな る組み合わせの数を出力するプログラムを作成してください。n 個の数はおのおの 0 から 9 までとし、1つの組み合わせに同じ 数字は使えません。たとえば、n が 3 で s が6 のとき、3 個の数 字の合計が 6 になる組み合わせは、 1 + 2 + 3 = 6 0 + 1 + 5 = 6 0 + 2 + 4 = 6 の三通りとなります。
  • 5. + Main public class Main { public static void main(String[] args){ BinaryPool binaryPool = new BinaryPool(10); Scanner sc = new Scanner(System.in); while(sc.hasNext()){ String[] strs = sc.nextLine().split(" "); int n = Integer.parseInt(strs[0]); int s = Integer.parseInt(strs[1]); if(n==0&&s==0){ break; } System.out.println(new Execution(binaryPool,n).getPattern(s)); } } } 入力文字列を空白でsplit、 intに変換。s,nが共に0の時 ループを抜ける。
  • 6. + Execution class Execution{ private ArrayList<String> binaryData; private HashMap<Integer,ArrayList<String>> result; public Execution(BinaryPool binaryPool,int n){ binaryData=binaryPool.getFilteredData(n); result=new HashMap<Integer, ArrayList<String>>(); analysis(); } private void analysis(){ for(String s:binaryData){ if(result.containsKey(listSum(decoder(s)))){ result.get(listSum(decoder(s))).add(makeFormula(decoder(s))); }else{ ArrayList<String> tmp = new ArrayList<String>(); tmp.add(s); result.put(listSum(decoder(s)),tmp); } } } 生成したビット列を合計値 で振り分ける
  • 7. + private String makeFormula(ArrayList<Integer> aList){ StringBuilder sb = new StringBuilder(); for(int i=0;i<aList.size();i++){ if(i==aList.size()-1){ sb.append(Integer.toString(aList.get(i))); }else{ sb.append(Integer.toString(aList.get(i))+"+"); } } return sb.toString(); } private ArrayList<Integer> decoder(String str){ ArrayList<Integer> tmp = new ArrayList<Integer>(); for(int i=0;i<str.length();i++){ if(str.charAt(i)=='1'){ tmp.add(i); } } return tmp; } リストを数式に変換する 4,7,9 -> 4+7+9 ビット列を数字のリストに変換する 0011000100 -> 2,3,7
  • 8. private int listSum(ArrayList<Integer> aList){ int s=0; for(int n:aList){ s+=n; } return s; } public int getPattern(int sum){ int s; try{ s=result.get(sum).size(); }catch (NullPointerException e){ s=0; } return s; } 入力sに対応するリストを取得し、 そのリストの長さをreturnする。 リストがnullの場合、入力された和 になるパターンは存在しないとい うことなので0をreturnする。 引数に与えられたリストの 和をreturnする
  • 9. + BinaryPool private int target; private String[] binaryData; public BinaryPool(int target){ this.target=target; binaryData = new String[(int)Math.pow(2,target)]; calculation(); } private void calculation(){ for(int i=0;i<binaryData.length;i++){ binaryData[i] = complementBin(Integer.toBinaryString(i)); } } private String complementBin(String str){ for(int i=str.length();i<target;i++){ str="0"+str; } return str; } コンストラクタ データ格納領域を確保する。 10bitの2進数全パターンは 2^10=1024通りあるのでその個 数分String配列を確保する。 0~1023を2進数に変換し、配 列に格納する。 生成した2進数を10bitに揃え る。例えば63=111111を 0000111111に変換する。
  • 10. public String[] getData(){ return binaryData; } public ArrayList<String> getFilteredData(int t) { ArrayList<String> tmp = new ArrayList<String>(); for (int i = 0; i < binaryData.length; i++) { if (countBit(binaryData[i]) == t) { tmp.add(binaryData[i]); } } return tmp; } private int countBit(String str){ int c=0; for(int i=0;i<str.length();i++){ if(str.charAt(i)=='1'){ c++; } } return c; } 全パターンデータのgetter 指定した個数分ビットが立って いるものをフィルタしてパター ンデータ取得 何個ビットが立っているか数える
  • 12. + 短くしてみた import java.util.Scanner; public class Main{ public static void main(String[] args){ Scanner sc = new Scanner(System.in); while(sc.hasNext()){ String[] strs = sc.nextLine().split(" "); int n = Integer.parseInt(strs[0]); int s = Integer.parseInt(strs[1]); if(n==0&&s==0) break; System.out.println(calculation(n,s)); } } private static int calculation(int n,int s){ int c=0; for(int i=0;i<(int)Math.pow(2,10);i++) if(countBit(complementBin(Integer.toBinaryString(i)))==n&&getSum(complementBin(Integer.toBinaryString(i))) ==s) c++; return c; } private static String complementBin(String str){ for(int i=str.length();i<10;i++) str="0"+str; return str; } private static int countBit(String str){ int c=0; for(int i=0;i<str.length();i++) if(str.charAt(i)=='1') c++; return c; } private static int getSum(String str){ int s=0; for(int i=0;i<str.length();i++) if(str.charAt(i)=='1') s+=i; return s; } }
  • 13. + C #include<stdio.h> #include<math.h> #define BIT 10 int bitArray[BIT]; void print(){ for(int i=0;i<BIT;i++){ printf("%d",bitArray[i]); } printf("n"); } int countBit(){ int c=0; for(int i=0;i<BIT;i++) if(bitArray[i]) c++; return c; } int getSum(){ int s=0; for(int i=0;i<BIT;i++) if(bitArray[i]) s+=i; return s; } void genBit(int n){ for(int i=0;i<BIT;i++){ bitArray[BIT-i-1]=n%2; n=n/2; } } int calculation(int n,int s){ int c=0; for(int i=0;i<(int)pow(2,BIT);i++){ genBit(i); //print(); if(countBit()==n&&getSum()==s) c++; } return c; } int main(void){ while(1){ int n,s; scanf("%d %d",&n,&s); if(n==0&&s==0){ break; } printf("%dn",calculation(n,s)); } return 0; }