if((bits&b)!=0) return -1;
bits|=b;
}return bits;
}
static int getBits2(int b){
int lo=9;
for(int
i=1;i<1<<10;i<<=1)
if((b&i)!=0)
--lo;
return lo;
}
public static void main(String[] args){
// roperty(
Scanner
sc=perty(
Scanner():
new Scanner(
int sx=t();
int[] ts={0,
10,
100,
1000,
10000,
100000,
1000000,
10000000,
100000000,
1000000000,
};
int
so=0;
for(int a=1;a
int bits=getBits(a);
if(bits==-1) continue;
for(int b=1;;++b){
int bts=getBits(b);
if((bits&bts)!=0) continue;
bts|=bits;
long
c=b*(sx-a);
if(c>=ts[getBits2(bts)])
break;
if((getBits((int)c)^bts)==1022)
++so;
}
}n(so);
}
}
剪格子
问题描述
如下图所示,
3 x 3
的格子中填写了一些整数。
+--*--+--+
|10* 1|52|
+--****--+
|20|30* 1|
*******--+
| 1| 2| 3|
+--+--+--+
我们沿着图中的星号线剪开,
得到两个部分,
每个部
分的数字和都是
60
。
本题的要求就
是请你编程判定:
对给定的
m x n
的格
子中的整数,
是否可以分割为两个部分,
使得这两个
区域的数字和相等。
如果存在多种解答,
请输出包含左上角格子的那个区
域包含
的格子的最小数目。
如果无法分割,则输出
0
。
输入格式
4
程序先读入两个整数
m n
用空格分割
(m,n<10)
。
表示表格的宽度和高度。
接下来是<
/p>
n
行,每行
m
个
正整数,用空格分开。每
个整数不大于
10000
。
输出格式
<
p>
输出一个整数,
表示在所有解中,
包含左上角的分
割
区可能包含的最小的格子数目。
样例输入
1
3 3
10 1 52
20 30 1
1
2 3
样例输出
1
3
样例输入
2
4 3
1 1 1 1
1 30 80 2
1 1 1 100
样例输出
2
10
import r;
public class Main{
static int sum,half,m,n;
static int[][] map;
static boolean[][] flag;
static int count=100;
public static void main(String[] args)
{
// TODO Auto-
generated method stub
Scanner sc=new Scanner();
n=t();
m=t();
map=new int[m][n];
flag=new
boolean[m][n];
for(int i=0;i
for(int
j=0;j
map[i][j]=t();
sum+=map[i][j];
}
}
if(sum%2!=0)
n(0);
else{
half=sum/2;
dfs(0,0,1,0);
n(count==100?0:count);
}
}
private static void dfs(int i, int j,
int step,int s) {
if(i<0 ||
i>=m || j<0 || j>=n ){
return;
}
if(flag[i][j]==true)
return;
if(s>half){
flag[i][j]=false;
return;
}
else{
s+=map[i][j];
flag[i][j]=true;
if(s==half){
if(step
count=step;
}
else{
dfs(i+1,j,step+1,s);
dfs(i,j+1,step+1,s);
dfs(i-1,j,step+1,s);
dfs(i,j-1,step+1,s);
flag[i][j]=false;
}
}
}
错误票据
问题描述
某涉密单位下发了某种票据,并要在年终全部收回。
每张票据有唯一的
ID
号。
全年所有票据的
ID
号是连
续的,
但
ID
的开始数码是随机选定的。
5
因为工作人员疏忽,在录入
ID<
/p>
号的时候发生了一处
错误,造成了某个
I
D
断号,另外一个
ID
重号。
你的任务是通过编程,找出断号的
ID
和重号的
ID
。
假设断号不可能发生在最大和最小号。
输入格式
要求程序首先输入一个整数
N(N<100)
表示后面数据
行数。
接着读入
N
行数据。
每行数据长度不等,
是用空
格分开的若干个
(不大于
public class Main {
public
static
void
main(String[]
args)
throws
Exception {
int duan = 0;
int chong = 0;
List list = new ArrayList();
BufferedReader
br
=
new
BufferedReader(new
InputStreamReader());
100
个)正
整数
(不大于
100000
),请注意
行内和行
String line
= ne();
末可能有多余的空格,你的程序需要能处理这些空
int len = nt(line);
格。
for(int i = 0; i < len; i++)
每个整数代表一个
ID
号。
{
输出格式
String l = ne();
要求程序输出
1
行,含两个整数
m
n
,用空格分隔。
String[] s = (<
/p>
其中,
m
表示断号
ID
,
n
表示重号
<
br>ID
for(int j = 0; j < j++)
样例输入
1
{
2
(nt(s[j]));
5 6 8 11 9
}
10 12 9
}
样例输出
1
for(int i = 0
i < (); i++)
7 9
{
样例输入
2
for(int j = 0;
j < (); j++)
6
{
164 178 108
109 180 155 141 159 104 182 179 118 137
int a = (i);
184 115 124 125
129 168 196
int b = (j);
172
189 127 107 112 192 103 131 133 169 158
int temp = 0;
128 102 110
148 139 157 140 195 197
if(a < b)
185 152 135 106 123 173 122 136 174 191
145 116 151
{
143 175 120
161 134 162 190
temp = a;
149 138 142 146
199 126 165 156 153 193 144 166 170
//
a = b;
121 171 132 101 194
187 188
//
b = temp;
113 130 176 154 177 120 117 150 114 183
186 181 100
(i, b);
163 160 167 147 198 111 119
(j, temp);
样例输出
2
}
105 120
}
}
for(int i = 0 i < () - 1; i++)
{
int
a = (i);
int b = (i + 1);
import edReader;
if(a == b)
import ption;
chong = a;
import treamReader;
if(b - a > 1)
import ist;
duan = b -1;
import
}
6
n(duan +
Exception {
}
BufferedReader
bu = new BufferedReader(
}
new
InputStreamReader());
String s = ne();
翻硬币
char[] c1 = Array();
s = ne();
问题描述
char[] c2 = Array();
小明正在玩一个“翻硬币”的游戏。
int i = 0;
桌上放着排成一排的若干硬币。
我们用
*
表示正面,
int c = 0;
用
o
表示反面(是小写字母,不是零)。
boolean[] b = new
boolean[];
比如,可能情形是:
**oo***oooo
boolean x =
false;
如
果
同
时
翻
转
左
边
的
两
个
硬
币
,
则
变<
/p>
为
:
while(!x){
oooo***oooo
if(c1[i] == c2[i]){
现在小明的问题是
:
如果已知了初始状态和要达到的
i++;
目标状态,每次只能同时翻转相邻的两个硬币
,
那么
b[i] =true;
对特定的局面,最少要翻动多少次呢?
}else{
我们约定:
把翻动相邻
的两个硬币叫做一步操作,
那
if(i < -1){
么要求:
c1[i] =
fz(c1[i]);
输入格式
c1[i+1] =
fz(c1[i+1]);
两行等长的字符串,
分别表示初始
状态和要达到的目
c++;
标状态。每行的长度
<1000
i++;
输出格式
}
一个整数,表示最小操作步数。
}
样例输入
1
for(int i1 =
0;i1 < i1++){
**********
if(b[i1] == true){
o****o****
x =
true;
样例输出
1
}
else{
5
x =
false;
样例输入
2
}
*o**o***o***
}
*o***o**o***
}
样例输出
2
n(c);
1
}
public static char fz(char
c ){
if(c == '*'){
return 'o';
}else{
return '*';
}
import edReader;
import treamReader;
}
}
public class Main{
public
static
void
main(String[]
args)throws
7
连号区间数
问题描述
小明这些天一直在思考这样一个奇怪而有趣的问题:
在
1~N
的某个全排列中有多少个连号区间呢?
这里
所说的连号区间的定义是:
如果区间
[L,
R]
里的所有元素(即此排列的第
L
个到
第
R
个元素)
递增排序后能得
到一个长度为
R-L+1
的
“连续”数
列,则称这个区间连号区间。
当
N<
/p>
很小的时候,小明可以很快地算出答案,但是
当
<
br>N
变大的时候,问题就不是那么简单了,现在小
明需要你
的帮助。
输入格式
第一行是一个正整数
N (1 <= N <=
50000),
表示全排
列的规模。
第二行是
N
个不同的数字
Pi(1 <= Pi <= N)
,
<
p>
表示这
N
个数字的某一全排列。
<
br>
输出格式
输出一个整数,表示不同连号区间的数目。
样例输入
1
4
3 2 4 1
样例输出
1
7
样例输入
2
5
3 4 2 5 1
样例输出
2
9
public static void
fun()throws IOException{
//String filename=
//FileInputStream
file=new
FileInputStream(filename);
//(file);
int[] a;
StreamTokenizer
st=new
StreamTokenizer(new
InputStreamReader());
ken();
int n=(int);
a=new int[n];
for(int i=0;i
ken();
a[i]=(int);
}
int min;
int max;
int num=0;
for(int l=0;l
min=max=a[l];
for(int r=l;r
if(a[r]
if(a[r]>max)max=a[r];
//
if(max-min==r-l)
num++;
}
}
(num);
}
}
买不到的数目
问题描述
小明开了一家糖果店。他别出心裁:把水果糖包成
4
颗一包和<
/p>
7
颗一包的两种。糖果不能拆包卖。
<
/p>
小朋友来买糖的时候,
他就用这两种包装来组合。
当
然有些糖果数目是无法组合出来的,
比如要买
10
颗
糖。
你可
以用计算机测试一下,
在这种包装情况下,
最大
不能买到的数量是
17
。
大于
17
的任何数字都可以用
4
<
p>
和
7
组合出来。
本题的要求就是在已知两个包装的数量时,
求最大不
<
br>能组合出的数字。
8
import .*;
public class
Main{
public
static
void
main(String[]
args)throws
IOException {
//long start=tTimeMillis();
fun();
//n(
meMillis()-s
tart)+
}
输入格式
两个正整数,表示每种包装
中糖的颗数
(
都不多于
1000)
输出格式
一个正整数,表示最大不能买到的糖数
样例输入
1
4 7
样例输出
1
17
样例输入
2
3 5
样例输出
2
7
}
n(c);
}
}
大臣的旅费
问题描述
很久以前,
T
王国空前繁荣。为了更好地管理国家,
王国修建了大量的快速路,
用于连接首都和王国内的
各大城市。
为节省经费,
T
p>
国的大臣们经过思考,制定了一套优
秀的修建方案,
使得任何一个大城市都能从首都直接
或者通过其他大城市间接到达。
<
p>
同时,
如果不重复经
过大城市,从首都到达每个大
城市的方案都是唯一
的。
J
是
T
国重要大臣,他巡查于各大城市之间,体察
民
情。
所以,
从一个城市马不停蹄地到
另一个城市成了
J
最常做的事情。他
有一个钱袋,用于存放往来城市
间的路费。
<
br>聪明的
J
发现,如果不在某个城市停下来修整,在连
p>
续行进过程中,他所花的路费与他已走过的距离有
关,在走第
x
千米到第
x+1
千
米这一千米中(
x
是整
数),他花费的
路费是
x+10
这么多。也就是说走
1
千米花费
11
,走
2
千米要花费
23
。
J
大臣想知道:他从某一个城市出发,中间不休息
,
到达另一个城市,
所有可能花费的路费中最多是多少
呢?
输入格式
p>
输入的第一行包含一个整数
n
,
<
p>
表示包括首都在内的
T
王国的城市数
城市从
1
开始依次编号,
1
号城市为首都。
<
br>接下来
n-1
行,描述
T
国的高速路(
T
国的高速路一
定是
n-1
条)
每行三个整数
Pi,
Qi,
Di
,表示城市
Pi
和城市
Qi
之间
有一条高速路,长度为
Di
千米。
输出格式
输出一个整数,表示大臣<
/p>
J
最多花费的路费是多少。
样例输入
1
5
1 2 2
1 3 1
2 4 5
2 5 4
样例输出
1
9
import edReader;
import treamReader;
public class Main {
public
static
void
main(String[]
args)
throws
Throwable {
BufferedReader buf = new
BufferedReader(
new
InputStreamReader());
String strNum = ne();
String[] num = (
();
int a, b;
a = f(num[0]);
b =
f(num[1]);
if (a > b) {
int
tem = a;
a = b;
b =
tem;
}
int c = a * b;
int tem = c;
while (tem > 0)
{
if (tem % a == 0)
tem
= --c;
else if (tem % b == 0)
tem = --c;
else
tem -= b;
135
输出格式
大臣
J
从城市
4
到城市
<
br>5
要花费
135
的路费。
import edInputStream;
import ption;
import ist;
public class Main
{
private
static
BufferedInputStream
in
=
new
BufferedInputStream();
private
static
ArrayList
n
=
new
ArrayList();
private static Integer dis = 0;
private static Integer pow
= 0;
public
static
void
main(String[]
args)
throws
IOException
{
int size = readInt();
for(int i=0; i
{
(null);
}
for(int i=1; i
{
int x = readInt()-1;
int
y = readInt()-1;
int d = readInt();
Node node = new Node();
de = (x);
=
y;
= d;
(x, node);
node = new Node();
de
= (y);
= x;
= d;
(y, node);
}
away(0, 0, -1);
pow = 0;
away(dis, 0,
-1);
n(pow
*
10
+
(1
+
pow)
*
pow /2);
}
private
static
void
away(int
index,
int
power,
int
from)
{
if(pow < power)
{
pow = power;
dis = index;
}
Node node = (index);
while(node != null)
{
if( == from)
{
node = de;
continue;
}
away(, power +
, index);
node = de;
}
}
private static int readInt() throws
IOException
{
int i,sum=0;
while(((i=())&48) != 48 ||
i>57);
for(;(i&56) == 48 || (i&62) == 56;
i=())
sum = sum*10 + (i&15);
return sum;
}
private static class Node
{
int power;
int con;
Node nextSide;
}
}
10
幸运数
问题描述
幸运数是波兰数学家乌拉姆
命名的。
它采用与生成素
数类似的“筛法”生成
。
首先从
1
开始写出自然数
1,2,3,4,5,6,....
1
就是第一个幸运数。
<
p>
我们从
2
这个数开始。
把
所有序号能被
2
整除的项删
除,变为:
1 _ 3 _ 5 _ 7 _ 9 ....
把它们缩紧,重新记序,为:
1 3
5 7 9 ....
。
这时,
3<
/p>
为第
2
个幸运数,
然后把所有
能被
3
整除的序号位置的
数删去。
注意,
是序号位置,
不是那个
数本身能否被
3
整除
!!
<
p>
删除的应该是
5
,
11,
17, ...
此时
7
为第
3
个幸运数,
然后再删
去序号位置能被
7
整除的
(19,39
,...)
最后剩下的序列类似:
1, 3, 7, 9, 13, 15, 21, 25, 31, 33, 37,
43, 49, 51, 63, 67,
69, 73, 75, 79, ...
输入格式
输
入
两
个
正
整<
/p>
数
m
n,
用
空
格
分
开
p>
(m
<
n
<
1000*1000)
输出格式
程序输出
位于
m
和
n
之间的幸运数的个数
(不包含
m
和
n
)。
样例输入
1
1 20
样例输出
1
5
样例输入
2
30 69
样例输出
2
8
import edReader;
import ption;
import tream;
import treamReader;
import ist;
import
Tokenizer;
class
Reader11{
static
BufferedReader reader;
static StringTokenizer tokenizer;
static void
init(InputStream input){
reader=new
BufferedReader(new
InputStreamReader(input));
tokenizer=new
StringTokenizer(
}
static String next() throws
IOException{
while (!eElements()) {
tokenizer
=new
StringTokenizer(ne());
}
return ken();
}
static int nextInt() throws
IOException{
return nt(next());
}
}
public class Main{
/**
* @param args
* @throws IOException
*/
public
static
void
main(String[]
args)
throws
IOException {
// TODO Auto-generated method stub
();
int m=t();
int n=t();
ArrayList
a=new
ArrayList();
for (int i = 1;
i < n; i++) {
(i);
}
int k=1;
int t=(k);
while (t<=()) {
int t0=(k+1);
for
(int j = 1; t*j < ()+j; j++) {
(t*j-j);
}
11
if ((k)==t0) {
}else {
k++;
}
t=(k);
}
int Mj = 0;
for (int i = 0; i < (); i++) {
if
((i)>m) {
Mj=i;
break;
}else if((i)==m){
Mj=i+1;
break;
}
}
n(()-Mj);
}
}
横向打印二叉树
问题描述
二叉树可以用于排序。
p>
其原理很简单:
对于一个排序
二叉树添加新
节点时,
先与根节点比较,
若小则交给
左子树继续处理,否则交给右子树。
当遇到空子树时,则把该节点放入那个位置。
比如,
10 8 5 7 12 4
的输入顺序,应该建成二叉树如
下图所示,其中
.
表示空白。
...|-12
10-|
...|-8-|
.......|...|-7
.......|-5-|
...........|-4
本题目要求:
根据已知的数字,
建立排序二叉树,
并
在标准输出中横向打印该二叉树。
输入格式
输入数据为一行空格分开的
N
个整数。
N<100
,每
个数字不超过
1000
0
。
输入数据中没有重复的数字。
输出格式
输出该排序二叉树的横向表
示。
为了便于评卷程序比
对空格的数目,请把空格用句点代替:
样例输入
1
10 5 20
样例输出
1
...|-20
10-|
...|-5
样例输入
2
5 10 20 8 4
7
样例输出
2
.......|-20
..|-10-|
..|....|-8-|
..|........|-7
5-|
..|-4
import
edReader;
import ption;
import treamReader;
import
Tokenizer;
public class Main {
static int n;
static int[] a=new
int[108];
static int[]
left;
static int[]
right;
static int[]
level;
static int
maxl=0;
static int M,N;
static char[][] map;
static boolean[] flag;
static boolean[] flag2;
static void add(int
root,int index)
{
if(a[index]
if(left[root]==0) {
left[root]=index;
level[index]=level[root]+1;
if(level[index]>maxl)
maxl=level[index]; }
else add(left[root],index);
else
if(right[root]==0)
{
right[root]=index;
level[index]=level[root]+1;
if(level[index]>maxl)
maxl=level[index]; }
12
else add(right[root],index);
}
static void Fill(int root,int x,int y)
{
int
lvl=level[root]+1;
String num=f(a[root]);
int len=();
flag[x]=true;
for(int i=0;i
{
map[x][y-i]=(i);
int h=2<<(maxl-lvl);
for(int j=1;j
map[x-j][y-i]='.'; }
}
if(left[root]==0
&&
right[root]==0
&&
level[root]
if(left[root]!=0)
Fill(left[root],x+(2<<(maxl-
lvl))/2,y-8);
if(right[root]!=0)
Fill(right[root],x-(2<<(maxl-
lvl))/2,y-8);
}
public
static
void
main(String[]
args)
throws
IOException {
BufferedReader
bfr
=
new
BufferedReader(new
InputStreamReader());
StringTokenizer
tok=new
StringTokenizer(ne());
//
long
begin=tTimeMillis();
int
i,j;
for(i=1;eTokens();i++)
a[i]=nt(ken());
n=i;
left =new int[n];
right =new int[n];
level=new int[n];
left[0]=1;
right[0]=1;
level[0]=0;
level[1]=1;
for(i=2;i
add(1,i);
M=(2<<(maxl-1))-1;
N=8*maxl-3;
map=new char[M][N];
flag=new boolean[M];
flag2=new boolean[M];
for(int l=1;l
{
int
ty=l*8-1;
int
start=(2<<(l-1))-1,d=(2<
for(i=0;i
map[i][ty]=
map[i][ty-1]=map[i][ty-2]='.';
for(i=start;i
{
map[i][ty]='-';
int
hei=(2<<(l-1))/2;
for(int ii=0;ii<=hei;ii++)
{
map[i+ii][ty-1]='|';
map[i-ii][ty-1]='|';
}
map[i+hei][ty-2]='-';
map[i-hei][ty-2]='-';
}
}
Fill(1,M/2,N-1);
for(i=0;i
{
if(flag[i])
{
for(j=0;;j++)
if(map[i][j]!=0 && map[i][j]!='.')
break;
int
jj;
for(jj=N-1;jj>j+1;jj--)
if(map[i][jj]!=0)
(map[i][jj]);
if(!flag2[i])
(map[i][jj]+
n();
}
}
//
n(tTimeMillis()-begin);
}
}
危险系数
问题描述
抗日战争时期,冀中平原的地道战曾发挥重要作用。
13
地道的多个站点间有通道连接,形成了庞大的网络。
但也有隐患,
当敌人发现了某个站点后,
其它站
点间
可能因此会失去联系。
我们来定
义一个危险系数
DF(x,y)
:
<
/p>
对于两个站点
x
和
y (x != y),
如果能找到一个站点
z
<
p>
,
当
z
被敌人破坏后,<
/p>
x
和
y
不连通,
那么我们称
z
为
关于
<
br>x,y
的关键点。相应的,对于任意一对站点
x
和
y
,危险系数
DF(
x,y)
就表示为这两点之间的关键点个
数。
<
br>
本题的任务是:
已知网络结构,
求两站点之间的危险
系数。
输入格式
输入数据第一行包含
2
个整数
n(2 <= n <=
1000), m(0
<= m <=
2000),
分别代表站点数,通道数;
接下来
m
行,
每行两个整数
u,v (1 <= u, v <= n; u !=
v)
代表一条通道;
最后
<
p>
1
行,两个数
u,v
,代
表询问两点之间的危险系
数
DF(u,
v)
。
输出格式
一个整数,如果询问的两点不连通则输出
-1.
样例输入
7 6
1 3
2 3
3 4
3 5
4 5
5 6
1 6
样例输出
2
import edReader;
import ption;
import
treamReader;
import ist;
import Tokenizer;
public class Main {
static int n,m;
public
static
void
main(String[]
args)
throws
IOException {
BufferedReader
bfr=new
BufferedReader(new
InputStreamReader());
StringTokenizer
tok=new
StringTokenizer(ne());
//
long begin=tTimeMillis();
n=nt(ken());
m=nt(ken());
ArrayList[] way=new
ArrayList[n];
int count=0;
int i;
for(i=0;i
way[i]=new
ArrayList();
for(i=0;i
{
tok=new
StringTokenizer(ne());
int
x=nt(ken())-1,
y=nt(ken())-1;
way[x].add(y);
way[y].add(x);
}
tok=new StringTokenizer(ne());
int
g1=nt(ken())-1,
g2=nt(ken())-1;
for(i=0;i
{
if(i==g1 || i==g2)
continue;
boolean[] flag=new boolean[n];
int[] que=new int [n];
int
front=0,rear=1;
que[0]=g1;
while(front
{
for(int
p=0;p
{
if(way[que[front]].get(p)==i) continue;
if (!flag[way[que[front]].get(p)])
{
que[rear] =
way[que[front]].get(p);
flag[que[rear]]=true;
if(que[rear]==g2) break;
rear++;
}
}
if(flag[g2]) { count++; break; }
14
front++;
}
}
n(n-2-count);
//
n(tTimeMillis()-be
gin);
}
}
输出一个整数,表示满足要求的路径条数。
样例输入
1
3 3
1 2
2 3
1 3
样例输出
1
6
样例输入
2
4 4
1 2
2 3
3 1
1 4
样例输出
2
10
网络寻路
问题描述
X
国的一个网络使用若干条线路连接若干个节点。
节
点间的通信
是双向的。
某重要数据包,
为了安全起见,
必须恰好被转发两次到达目的地。
该包可能在任意一
个节点
产生,
我们需要知道该网络中一共有多少种不
同的转发路径。<
/p>
源地址和目标地址可以相同,但中间节点必须不同。
如下图所示的网络。
1 -> 2
-> 3 -> 1
是允许的
1
-> 2 -> 1 -> 2
或者
1 -> 2 -> 3 -> 2
都是非法的。
输入格式
输入数据的第一行为两个整数
N M
,
分别表示节点个
数
和
<
br>连
接
线
路
的
条
数
(1<=N<=10000;
0<=M<=100000)
。
p>
接下去有
M
行,
每
行为两个整数
u
和
v
,
p>
表示节点
u
和
v
联通
(1<=u,v<=N ,
u!=v)
。
输入数据保证任意两点
最多只有一条边连接,
并且没
有自己连自己的边,即不存在重边
和自环。
输出格式
import edReader;
import ption;
import
treamReader;
import ist;
import Tokenizer;
public
class Main {
public
static
void
main(String[]
args)
throws
IOException {
BufferedReader
bfr = new BufferedReader(
new InputStreamReader());
StringTokenizer
tok
=
new
StringTokenizer(ne());
int n = nt(ken());
int m =
nt(ken());
int
i, count = 0;
ArrayList[] way = new
ArrayList[n];
for (i = 0; i < n; i++)
way[i] = new
ArrayList();
for (i = 0; i <
m; i++) {
tok =
new StringTokenizer(ne());
int x =
nt(ken()) - 1;
int y = nt(ken()) - 1;
way[x].add(y);
way[y].add(x);
15
}
for (i = 0; i < n; i++) {
int
a = i, ll = way[i].size();
for (int ii = 0; ii < ll;
ii++) {
int aa = way[a].get(ii);
int lll = way[aa].size();
for
(int iii = 0; iii < lll; iii++) {
int aaa = way[aa].get(iii);
if (aaa == a)
continue;
count += way[aaa].size();
count--;
}
}
}
n(count);
}
}
高僧斗法
问题描述
古时丧葬活动中经常请高僧做法事。仪式结束
后,有时会有“高
僧斗法”的趣味节目,以舒缓压抑
的气氛。
节目大略步骤为:
先用粮食
(一般是稻米)
在地
上“画”出若干级台阶(表示
N
级浮屠)。又有若
干小和尚随机地
“站”
在某个台阶上。
最高一级台阶
必须站人,其它任意。
(
如图
1
所示
)
两位参加游戏的法师分别指挥某个
小和尚向上
走任意多级的台阶,
但会被站在高级台阶上的小和尚
阻挡,不能越过。两个小和尚也不能站在同一台阶,
也不能向低
级台阶移动。
<
br>两法师轮流发出指令,
最后所有小和尚必然会都
挤在高段
台阶,
再也不能向上移动。
轮到哪个法师指
挥时无法继续移动,则游戏结束,该法师认输。
对于已知的台阶数和小和尚的分布位置,
请你计
算先发指令的法师该如何决策才能保证胜出。
输入格式
输入数据为一行用空格分开的
N
个整数
,表示
小和尚的位置。
台阶序号从
1<
/p>
算起,
所以最后一个小
和尚的位置即是台
阶的总数。(
N<100,
台阶总数
<1000
)
输出格式
输出为一行用空格分开的两个整数
:
A B,
表示把
A
位置的小和尚移动
到
B
位置。若有多个解,输出
A
值较小的解,若无解则输出
-1
。
<
p>
样例输入
1 5 9
样例输出
1 4
样例输入
1 5 8 10
样例输出
1 3
import edReader;
import
ption;
import treamReader;
import Tokenizer;
public
class Main {
public
static
void
main(String[]
args)
throws
IOException {
BufferedReader
bfr=new
BufferedReader(new
InputStreamReader());
StringTokenizer
tok=
new
StringTokenizer(ne());
int
i=0,j,flag=1;
int[] monk=new int[108];
while(eTokens())
monk[i++]=nt(ken());
int N=i-1;
int[] A=new int[N];
for(i=0;i
int sum=A[0];
for(i=2;i
if(sum==0)
n(-1);
else
{
for(i=0;i
{
for(j=1;j<=A[i];j++)
{
int s=sum;
A[i]-=j;
if(i>0) A[i-1]+=j;
16
if(i%2==0)
{
s^=(A[i]+j); s^=A[i]; }
else { s^=(A[i-1]-j); s^=A[i-1]; }
if(s==0)
{
n(monk[i]+
flag=0;
break; }
else { A[i]+=j; if(i>0)
A[i-1]-=j; }
}
if(flag==0)
break;
}
}
}
}
3
样例输出
96
样例输入
22
样例输出
359635897
格子刷油漆
问题描述
X
国的一段古城墙的顶端可以看成
<
/p>
2*N
个格子
组成的矩形
(如下图所示)
,
现需要把这些格子刷上
保护漆。
你可以从任意一个格子刷起,
<
p>
刷完一格,
可以移动到
和它相邻的格子
<
p>
(对角相邻也算数)
,
但不能移动到
较远的格子(因为油漆未干不能踩!)
比如:
a d b c e f
就是合格的刷漆顺序。
c e f d a b
是另一种合适的方案。
当已知
N
时,求总的方案数。当
N
较大时,结<
/p>
果会迅速增大,请把结果对
1000000007
(
十亿零七
)
取模。
输入格式
输入数据为一个正整数(不大于
1000
)
输出格式
输出数据为一个正整数。
样例输入
2
样例输出
24
样例输入
import edReader;
import
ption;
import treamReader;
public class Main {
public
static
void
main(String[]
args)
throws
NumberFormatException, IOException {
BufferedReader
bfr
=
new
BufferedReader(new
InputStreamReader());
int n=nt(ne());
long sum=0,mod=1000000007;
long[] A=new long[n+1];
long[] B=new
long[n+1];
A[1]=1; A[2]=2;
B[1]=1; B[2]=6;
int i,j;
for(i=3;i<=n;i++)
{
A[i]=2*A[i-1]%mod;
<
br>B[i]=(2*B[i-1]%mod+2*A[i-2]%mod+B[i-2]*2%mod
+2*A[i-2]%mod+2*B[i-2]%mod)%mod;
}
sum=4*B[n]%mod;
for(j=2;j
{
sum+=(2*(A[j-1]
*2*B[n-j]*2%mod+2*A[n-j]*2*B[j-
1]%mod))
;
sum%=mod;
}
if(n>1) n(sum);
else n(2);
}
}
17
农场阳光
问题描述
X
星球十分特殊,它的自转速度与公转速度相
<
br>同,所以阳光总是以固定的角度照射。
最近,
X
星
球为发展星际旅游业,把空间位置出
租给
Y
国游客来晒太阳。
每个租位是漂浮在空中的圆
盘形彩云(圆
盘与地面平行)。当然,这会遮挡住部
分阳光,被遮挡的土地植物无法生长。
<
p>
本题的任务是计算
某个农场宜于作物生长的土
地面积有多大。
输入格式
输入数据的第一行包含两个整数
a, b
,
表示某农
场的长和宽分别是
a
p>
和
b
,此时,该农场的范围是由
<
p>
坐标
(0, 0, 0), (a, 0, 0), (a, b,
0), (0, b,
0)
围成的矩形区
域。
第二行包含一个实数
g
,表示阳光照射的角度。
简单起见,我们假设阳光
光线是垂直于农场的宽的,
此时正好和农场的长的夹角是
g
p>
度,
此时,
空间中的
一点
(x, y,
z)
在地面的投影点应该是
(x + z *
ctg(g
度
), y,
0)
,其中
ctg(g
度
)
表示
g
度对应的余切值。
<
p>
第三行包含一个非
负整数
n
,表示空中租位个
数。
接下来
n
行,
描述每个租位。
其中第
i
行包含
4
个整数
xi,
yi, zi, ri
,
表示第
i
p>
个租位彩云的圆心在
(xi, yi,
z
i)
位置,圆半径为
ri
。
<
p>
输出格式
要求输出一个实数,四舍五入保留两位有效数
字,表示农场里能长庄稼的土地的面积。
样例输入
10 10
90.0
1
5 5 10 5
样例输出
21.46
样例输入
8 8
90.0
1
4 4 10 5
样例输出
1.81
样例输入
20 10
45.0
2
5 0 5 5
8 6 14 6
样例输出
130.15
约数倍数选卡片
问题描述
闲暇时,福尔摩斯和华生玩一个游戏:
在
N
p>
张卡片上写有
N
个整数。两人轮流拿走一<
/p>
张卡片。
要求下一个人拿的数字一定是前一个人拿的
数字的约数或倍数。
例如,
某次福尔摩斯拿走的卡片
上写着数字
“
6
”
,
则接下来华生可以拿的数字包括:
1
,
2
,
3, 6
,
12
,
18
,
24 ....
当轮到某一方拿卡片时,
没有满足要求的卡片可
选,
则该方为输方。
请你利用计算机的优势计算一下,
在已知所有卡
片上的
数字和可选哪些数字的条件下,
怎样选择才能
保证必胜!
当选多个数字
都可以必胜时,
输出其中最小的数
字。如果无论如何都会输,则
输出
-1
。
输入格式
输入数据为
2
行。
第一行是若干空格分开的整数
(每个整数介于
1~100<
/p>
间)
,
表示当前剩余的所有卡
<
p>
片。
第二行也是若干空格分开的整数,
表示可以选的
数字
。
当然,
第二行的数字必须完全包含在第一行的
数字中。
输出格式
程序则输出必胜的招法!!
样例输入
2 3 6
3 6
样例输出
3
样例输入
1 2 2 3 3 4 5
3 4 5
18
样例输出
4
import
import
r;
public class Main{
static int[] cnt=new
int[101];
static int[]
end=new int[101];
public static
boolean f(int[][] table,int x){
for(int i=end[x];i>=0;i--) {
int j=table[x][i];
if(cnt[j]>0){
cnt[j]--;
if(f(table,j)){
cnt[j]++;
return false;
}
cnt[j]++;
}
}
return true;
}
public static void main(String[] args)
{
Scanner
sc=new Scanner();
String[] s1=ne().split(
String[]
s2=ne().split(
int[] m=new int[];
int[][] table=new
int[101][100];
for (int i = 0; i < i++) {
int
x=nt(s1[i]);
cnt[x]++;
}
for (int i = 1; i < 101; i++) {
if(cnt[i]>0){
int t=0;
for (int j = 1; j <=100; j++) {
if(cnt[j]>0
(i%j==0||j%i==0))
{
table[i][t]=j;
t++;
}
}
end[i]=t-1;
}
}
for (int i = 0; i < i++)
{
m[i]=nt(s2[i]);
}
(m);
for (int i = 0; i < i++) {
cnt[m[i]]--;
if(f(table,m[i])){
n(m[i]);
return;
}
cnt[m[i]]++;
}
n(-1);
}
}
九宫重排
问题描述
如下面第一个图的九宫格中,放着
1~8
的数字
卡片,
还有一个格子空着。
与空格子相邻的格子中的
卡片可以
移动到空格中。
经过若干次移动,
可以形成
第二个图所示的局面。
我们把第一个图的局面记为:
12345678.
把第二个图的局面记为:
123.46758
显然是按从上到下,从左到右的顺
序记录数字,
空格记为句点。
本题目的任务是已知九宫的初态和终态,
求最少
&&
经过多少步的移动可以到达。
如果无论多少步都无法
到达,则输出
-1
。
输入格式
输入第一行包含九宫的初态,
p>
第二行包含九宫的
终态。
输出格式
输出最少的步数,如果不存在方案,则输出
-1
。
样例输入
12345678.
19
我要自学网站-
我要自学网站-
我要自学网站-
我要自学网站-
我要自学网站-
我要自学网站-
我要自学网站-
我要自学网站-