1-三角形面积
![](https://i-blog.csdnimg.cn/blog_migrate/184490f2045d16ea92c8f98dd8ca5a45.png)
思路:
割补法求三角形面积
s=矩形面积-3个小三角形面积
答案:
28
代码:
import java.io.IOException;
import java.io.PrintWriter;
public class _1三角形面积 {
static PrintWriter pw=new PrintWriter(System.out);
public static void main(String args[]) throws IOException{
pw.println(8*8-(4*8)/2-(4*6)/2-(2*8)/2);
pw.close();
}
}
2-立方变自身
![](https://i-blog.csdnimg.cn/blog_migrate/ef2da4242198208c71246cf964c0f438.png)
思路:
由于100^3=1000000 有六位数,就算全为9,6*9=54<100,因此不可能立方变自身,比100大的数更不可能立方变自身;
因此只需要枚举判断100内符合条件的有多少个数即可
答案:
6
代码:
import java.io.PrintWriter;
public class _2立方变自身 {
static PrintWriter pw=new PrintWriter(System.out);
public static void main(String args[]) throws IndexOutOfBoundsException{
int res=0;
for(int i=1;i<=100;i++){
int sum=0;
int t= (int)Math.pow(i,3);
while (t!=0){
sum+=t%10;
t/=10;
}
if(sum==i) res++;
}
pw.println(res);
pw.close();
}
}
3-三羊献瑞
![](https://i-blog.csdnimg.cn/blog_migrate/16d21b1d76ad0081c952668080ed0481.png)
思路:
题目转化为等式:abcd+efgb=efcbh;只用到了8个数
其中a~h用a[0]~a[7]表示
思路:对10进行全排列,对于每种情况判断等式是否成立
答案:
1085
代码:
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashSet;
import java.util.Set;
public class _3三羊献瑞 {
static PrintWriter pw=new PrintWriter(System.out);
static int n;
static int N=20;
static int a[]=new int[N];
static boolean flag[]=new boolean[N];
static Set<Integer>set=new HashSet<>();
public static boolean check(){
int x=a[0]*1000+a[1]*100+a[2]*10+a[3];
int y=a[4]*1000+a[5]*100+a[6]*10+a[1];
int z=a[4]*10000+a[5]*1000+a[2]*100+a[1]*10+a[7];
if(x+y==z) return true;
return false;
}
public static void dfs(int u){
if(u==n){
if(a[4]==1){//e一定为1
if(check()){
int x=a[4]*1000+a[5]*100+a[6]*10+a[1];
set.add(x);
}
}
return;
}
for(int i=0;i<n;i++){
if(!flag[i]){
a[u]=i;
flag[i]=true;
dfs(u+1);
flag[i]=false;
}
}
}
public static void main(String args[]) throws IOException{
n=10;
dfs(0);
for(int t:set) pw.println(t);
pw.close();
}
}
4、5题为代码填空题,跳过
6-加法变乘法
![](https://i-blog.csdnimg.cn/blog_migrate/c032b2a44657751163abcd8f3aa65061.png)
思路:
i+j变为i*j相当于增大了i*j-i-j,因此枚举所有可以变号的位置,令两次变号后值增大2015-1225即可;
答案:
16
代码:
import java.io.*;
public class _6加法变乘法 {
static StreamTokenizer st=new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
static PrintWriter pw=new PrintWriter(System.out);
public static void main(String args[]) throws IOException{
for(int i=1;i<=46;i++){
for(int j=i+2;j<=48;j++){
if(i*(i+1)-i-(i+1)+j*(j+1)-j-(j+1)==2015-1225){
if(i!=10) pw.println(i);
// pw.println(i+" "+j);
}
}
}
pw.close();
}
}
7-牌数种类
![](https://i-blog.csdnimg.cn/blog_migrate/d34a635c32e72e23a833125363ca6ccd.png)
思路:
dfs爆搜所有方案,dfs(u,cnt),表示选到第u+1张牌(说明已经选完第u张牌),目前牌数为cnt
答案:
3598180
代码:
import java.io.IOException;
import java.io.PrintWriter;
public class _7牌数种类 {
static PrintWriter pw=new PrintWriter(System.out);
static int res=0;
public static void dfs(int u,int cnt){//当前要选u,总牌数为cnt
if(u>14 || cnt>13) return;
if(u==14 && cnt==13){//选完13即u==14,并且总牌数为13代表已经选牌完毕
res++;
return;
}
for(int i=0;i<=4;i++){//代表选了i张u
dfs(u+1,cnt+i);
}
}
public static void main(String args[]) throws IOException{
dfs(1,0);//从1开始选,总牌数为0
pw.println(res);
pw.close();
}
}
8-饮料换购
![](https://i-blog.csdnimg.cn/blog_migrate/46276bc92aa7191776727807a8e60c18.png)
思路:
直接模拟即可
代码:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
public class _8饮料换购 {
static BufferedReader bf=new BufferedReader(new InputStreamReader(System.in));
static PrintWriter pw=new PrintWriter(System.out);
static int n;
public static void main(String args[]) throws IOException{
n=Integer.parseInt(bf.readLine());
int res=n;
while (n>=3){
res+=n/3;
n=n/3+n%3;
}
pw.println(res);
pw.close();
}
}
9-垒骰子
![](https://i-blog.csdnimg.cn/blog_migrate/491b6c6def81aa8761f76650179eb492.png)
思路:
矩阵乘法+快速幂
状态表示 集合:f(i,j)表示由i个骰子垒在一起,最上面的数字是j的所有合法方案的集合; 属性:数量
状态计算 按照倒数第二个骰子最上面的数字划分集合,则f(i,j)=Σ(k:1~6)f(i-1,k)*x(x为0或4,若不排斥则为4,排斥为0)
将f(i,j)用一个向量F(i)进行表示,F(i)共有6个参数,表示前i个骰子,最上面数字分别为0~6时的方案数,因此F[1]={4,4,4,4,4,4};
则a矩阵是由x构成的,x只能为0或4,由于每层的限制都是一样的,所以限制一旦确定,则x的取值就固定了,因此通过题目输入的限制确定a矩阵;
为了少写一个一维与二维矩阵相乘的mul函数,将F[i]扩展为二维,但只有第一行有数字,其余数字均为0;
F(n)=F(1)*a^(n-1),利用快速幂求解;
求F(n)即可得到前n个骰子,最上面点数为1~6的方案数,res即为所有的方案数相加;
代码:
import java.io.*;
import java.util.Arrays;
public class _9垒骰子 {
static StreamTokenizer st=new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
static PrintWriter pw=new PrintWriter(System.out);
public static int nextInt() throws IOException{
st.nextToken();
return (int)st.nval;
}
static int n,m;
static int N=6;
static int mod=(int)1e9+7;
static int a[][]=new int[N][N];
static int F[][]=new int[N][N];
public static int get_op(int x){//得到x的对面是几
if(x>=3) return x-3;
else return x+3;
}
public static void mul(int c[][],int a[][],int b[][]){
int temp[][]=new int[N][N];
for(int i=0;i<N;i++){
for(int j=0;j<N;j++){
for(int k=0;k<N;k++){
temp[i][j]=(int)((temp[i][j]+(long)a[i][k]*b[k][j])%mod);
}
}
}
for(int i=0;i<N;i++){
for(int j=0;j<N;j++){
c[i][j]=temp[i][j];
}
}
}
public static void main(String args[]) throws IOException{
n=nextInt();
m=nextInt();
//初始化,若不考虑限制,则不管最上面的数是几,均可转动四次得到4个不同的方案,因此初始化为全4
for(int i=0;i<N;i++) Arrays.fill(a[i],4);
while (m--!=0){//读入限制,得到最终的a矩阵
int x=nextInt();
int y=nextInt();
x--;y--;//统一为下标从0开始,1~6->0~5;
a[x][get_op(y)]=0;
a[y][get_op(x)]=0;
}
//得到f[1],设为二维但只有第一行有数,其余均为0,目的是为了少写一个mul函数
for(int i=0;i<N;i++) F[0][i]=4;//F[1]={4,4,4,4,4,4};虽然是二维但其余均为0
int k=n-1;//F(n)=F(1)*a^(n-1);
while (k!=0){//快速幂求F[n],结果均在F[1]中
if((k&1)==1) mul(F,F,a);//F=F*a
mul(a,a,a);//a=a*a
k>>=1;
}
int res=0;//最终结果为6种情况之和
for(int i=0;i<N;i++) res=(res+F[0][i])%mod;
pw.println(res);
pw.close();
}
}
10-生命之树
![](https://i-blog.csdnimg.cn/blog_migrate/1ed0129a4bdf09f608465f205406e82c.png)
思路:
f(u):表示以u为根的子树中,包含u这个点的所有连通块的权值最大值
假如u有k个儿子,分别为s[1]、s[2]···s[k];
则f(u)=w[u]+Σ(i:1~k)(max(f(s[i],0))) 如果某个儿子的权值小于0,则不要它
因此求出所有f[i],其中的最大值即为答案
代码:
import java.io.*;
import java.util.Arrays;
public class _10生命之树 {
static StreamTokenizer st=new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
static PrintWriter pw=new PrintWriter(System.out);
public static int nextInt() throws IOException{
st.nextToken();
return (int)st.nval;
}
static int n;
static int N=100010;
static int M=2*N;
static long f[]=new long[N];
static int h[]=new int[N];
static int e[]=new int[M];
static int ne[]=new int[M];
static int w[]=new int[N];
static int idx=0;
public static void add(int a,int b){
e[idx]=b;
ne[idx]=h[a];
h[a]=idx++;
}
public static void dfs(int u,int fa){
f[u]=w[u];
for(int i=h[u];i!=-1;i=ne[i]){
int j=e[i];
if(j!=fa){
dfs(j,u);
f[u]+= Math.max(f[j],0);
}
}
}
public static void main(String args[]) throws IOException{
n=nextInt();
for(int i=1;i<=n;i++) w[i]=nextInt();
Arrays.fill(h,-1);
for(int i=0;i<n-1;i++){
int a=nextInt();
int b=nextInt();
add(a,b);
add(b,a);
}
dfs(1,-1);//dfs求解所有f[i]的值
long res=Long.MIN_VALUE;
for(int i=1;i<=n;i++) res= Math.max(res,f[i]);
pw.println(res);
pw.close();
}
}