工厂需要采购一批产品,现有3种家公司进入采购名单,为了保证质量足够统一。选了一家公司就采购同一批次的所有产品。每家公司由于生产线不同,每一批产品的价格和数量也不同。
问:在能满足公司需求的情况下最少花费多少钱才能采购完成。
输入格式
第一行包含一个正整数n,表示需要的产品数量。
接下来三行,每行用2个正整数描述此公司一批产品:其中第1个整数表示这种产品一批次的数量,第2个整数表示这种产品一批次的价格。
保证所有的7个数都是不超过10000的正整数。
输出格式
1个整数,表示最少需要花费的钱。
A题,看题目,只选同一家公司的产品,直接秒杀,贴代码了
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StreamTokenizer;
public A {
static int GS[][];
public static void main(String[] args) throws IOException {
PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
StreamTokenizer in = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
int min=Integer.MAX_VALUE;
in.nextToken();
int target=(int)in.nval;
GS=new int[3][2];
for(int i=0;i<3;i++){
for(int j=0;j<2;j++){
in.nextToken();
GS[i][j]=(int)in.nval;
}
}
for(int i=0;i<3;i++){
if(help(target,GS[i][0])==true){
min=Math.min(target/GS[i][0]*GS[i][1], min);
}else{
min=Math.min(((target/GS[i][0])+1)*GS[i][1], min);
}
}
out.print(min);
out.flush();
}
public static boolean help(int a,int b){
if(a%b==0){
return true;
}
return false;
}
}
B
现在有两张清单。清单A有N个字符串,清单B有M个字符串。
现在需要以A为标准,检验B中的字符串。
对于B中的每个字符串:
若A中没有则输出 NO
若A中有则输出 YES;
若A中有且在B中第二次出现则输出 REPEAT;
输入格式
第一行N表示A中有的字符串
后续N行每行一个字符串。字母全部小写,且长度小于50大于0;
第N+2行整数M表示B中的字符串数
后续M行每行一个字符串。字母全部小写,且长度小于50大于0;
两个集合搞定,贴代码
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StreamTokenizer;
import java.util.HashSet;
import java.util.Set;
public class {
public static void main(String[] args) throws IOException{
PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
StreamTokenizer in = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
Set<String> seta= new HashSet();
Set<String> setb= new HashSet();
in.nextToken();
int N=(int)in.nval;
for(int i=0;i<N;i++){
in.nextToken();
seta.add(in.sval);
}
in.nextToken();
int M=(int)in.nval;
for(int i=0;i<M;i++){
in.nextToken();
String tmp=in.sval;
if(seta.contains(tmp)){
if(setb.contains(tmp)){//第二次出现
out.println("REPEAT");
out.flush();
}else {
out.println("YES");
out.flush();
}
}else{
out.println("NO");
out.flush();
}
setb.add(tmp);
}
}
}
C
题目描述
图书馆有一堆图书,为了方便查找每本书都有自己的编号。
小明是图书馆的常客,现在图书馆将小明一年的借书都提取出来了,不过由于系统故障导致图书编号发生了重叠。
现在求助于你,请问小明借的书中出现最多的书的次数和编号。
输入格式
第一行一个数表示图书馆馆藏n n<200
接下来的n行每行一个图书的编号只包含大小写字母且不长于80
最后一行小明写的编号只包含大小写字母,长度小于1000000
这道题我觉得是KMP算法,但是我忘记模板了,然后用暴力跑分,没跑出来...老师说是用trie,等大神
D
题目描述
现在有个神奇的湖,
如果将BAA的B端碰触水面则字符串会增长为AABBAA
如果将BBA的A端碰触水面则字符串会增长为BBAABB
现在给出一个字符串请输出此字符串碰触湖水前的最小长度。
(一个字符串可操作多次或者不操作)
输入格式
一个用A和B组成的字符串 长度<100000
仔细看题目,很容易想到二分法,然后再套一个逆转字符串,秒杀,上代码。
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StreamTokenizer;
public class {
static String S;
public static void main(String[] args) throws IOException {
PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
StreamTokenizer in = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
in.nextToken();
S=in.sval;
// System.out.println(S.substring(0,3+1));
// System.out.println(S.substring(3+1,8));
System.out.println(erfen());
}
public static int erfen(){
int left = 0;
int right = S.length()-1;
while (left <= right) {
int middle = (left+right)/2;
if(S.substring(0,middle+1).equals(nizhuan(S.substring(middle+1,right+1)))){
//继续判断,直接选择左边
right=middle;
}else{
return right-left+1;//没办法继续分了
}
}
return -1;
}
static public String nizhuan(String sss){
StringBuffer sb=new StringBuffer(sss);
return sb.reverse().toString();
}
}
E
题目描述
有一个游戏会给出如下数据
4
0 0 0 0
0 1 1 1
0 1 0 1
0 1 1 1
将被封死的0变为2
0 0 0 0
0 1 1 1
0 1 2 1
0 1 1 1
输入格式
n<31
提示(每组只会有一个满足的闭合的多边形)
思路:DFS,把所有的封闭图形外边的点过一遍标记一下,里面的点到达不了的就是我们要求的点,上代码。
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StreamTokenizer;
public class M {
static int [][]G;
static int N;
public static void main(String[] args) throws IOException {
PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
StreamTokenizer in = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
in.nextToken();
N=(int)in.nval;
G=new int[N][N];
for(int i=0;i<N;i++){
for(int j=0;j<N;j++){
in.nextToken();
G[i][j]=(int)in.nval;
}
}
for(int i=0;i<N;i++){//从边界开始全部封闭
dfs(i,0);
dfs(i,N-1);
dfs(0,i);
dfs(N-1,i);
}
for(int i=0;i<N;i++){
for(int j=0;j<N;j++){
if(G[i][j]==9){
out.print(0);
out.print(" ");
}else if(G[i][j]==1){
out.print(1);
out.print(" ");
}else if(G[i][j]==0){
out.print(2);
out.print(" ");
}
}
out.println();
out.flush();
}
}
public static void dfs(int i, int j) {
if (i<0 || j<0 || i>=N || j>=N) {
return;
}
if (G[i][j] == 1||G[i][j] ==9) {
return;
}
G[i][j] = 9;
dfs(i - 1, j);
dfs(i + 1, j);
dfs(i, j - 1);
dfs(i, j + 1);
}
}
题目描述
在路上设置了 n 个驿站1,2,⋯,n。行人可在这些驿站租用马车,并在之后的任何一个驿站归还马车。驿站 i 到驿站 j 之间的租金为 r(i,j)(1≤i<j≤n)。试设计一个算法,计算出从驿站 1 到驿站 n 所需的最少租金。
输入格式
第一行中有一个正整数 n,表示有 n 个驿站。接下来的 n−1 行是一个半矩阵 r(i,j)(1≤i<j≤n)。
思路:迪杰斯特拉算法套用一下,秒杀
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StreamTokenizer;
public class {
static int n;
static int G[][];
static int dis[];
static boolean vis[];
public static void main(String[] args) throws IOException {
PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
StreamTokenizer in = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
in.nextToken();
n=(int)in.nval;
G=new int[n+2][n+2];
dis=new int[n+1];
vis=new boolean[n+1];
for(int i=1;i<n;i++){//上三角矩阵
for(int j=i+1;j<=n;j++){
in.nextToken();
G[i][j]=(int)in.nval;
}
}
dj(1);
out.println(dis[n]);
out.flush();
}
static void dj(int s){//迪杰斯特拉
for(int i=1;i<=n;i++){
dis[i]=G[s][i];//dis存储从s到其余驿站的最小租金
vis[i]=false;
}
vis[s]=true;
dis[s]=0;//自身为0
for(int i=1;i<n;i++){//循环n-1次;
int min=Integer.MAX_VALUE;
int index=s;
for(int j=1;j<=n;j++){//找到最小值和下标
if(vis[j]==false && dis[j]<min && dis[j]!=0){
min=dis[j];
index=j;
}
}
vis[index]=true;
for(int j=1;j<=n;j++){//更新最优
if( vis[j]==false && G[index][j]!=0){
dis[j]=Math.min(dis[index]+G[index][j],dis[j]);
}
}
}
}
}