比賽鏈接https://www.luogu.com.cn/contest/56279
代碼是看了直播講解之后寫(cv)出來的~
A題:
聽了直播講解后……我才明白這題是純純暴力啊,我還以為要用string判斷再轉回int啥啥啥的……
這份代碼是C++的
#include <bits/stdc++.h>
using namespace std;
int main(){
int n, k;
scanf("%d%d", &n, &k);
int index, i;
int num = 0; //判斷3的個數
// //如果n為偶數的話肯定不滿足題意的
// //為后面的循環降低一點循環次數
// if(n % 2 == 0){
// n++;
// }
for(i = n; ; i++){
index = i; //暫存現在循環到的這個數
//對index做拆分,不影響i的值
while(index != 0){
//當index此時取余得到改數末尾的數字為3時,num++
if(index % 10 == 3){
num++;
}
index /= 10; //除以十進入下次循環用來判斷
}
//當index = 0時,就證明i被拆分完了,
//判斷一下此時的num和k是否相等
//相等就代表我們找到答案了
if(num == k){
break;
}
//num置為0
num = 0;
}
printf("%d", i);
return 0;
}
這是java的代碼,原理其實是一樣的。
import java.util.Scanner;
public class Main {
//我還不會除了Scanner外的輸入方式,所以只能用這個了
static Scanner input;
public static void main(String[] args) {
input = new Scanner(System.in);
int n = input.nextInt();
int k = input.nextInt();
int i = n;
int index = 0;
int num = 0;
//這個循環是一直直到找到答案為止的,所以是死循環
while(true) {
index = i;
while(index != 0) {
if(index % 10 == 3) {
num++;
}
index /= 10;
}
if(num == k) {
break;
}
//不是for循環,所以需要重新賦值的條件往后放
num = 0;
i++;
}
//出了循環就代表答案出來了
System.out.println(i);
}
}
B題:
C++的代碼
#include <bits/stdc++.h>
using namespace std;
const int N = 105;
int a[N];
int main(){
int n, id;
scanf("%d", &n);
//a數組純粹是判斷某個1-100的數字是不是已經輸入過了
//為了防止初始值有問題,所以賦值一下
//為了省空間的話用bool數組是最好的
memset(a, 0, sizeof(a));
for(int i = 0; i < n; i++){
scanf("%d", &id);
//如果id已經輸入過了就continue
//如果id沒有輸入就輸出 並且 把a[id]賦值為1
if(!a[id]){
//如果已經輸入了,進不來這個條件
printf("%d ", id);
a[id] = 1;
}
}
return 0;
}
java代碼。
正好我最近學到了集合,所以用的集合寫的。
這是比賽時的源碼,所以沒有注釋。
import java.util.ArrayList;
import java.util.Scanner;
public class Main {
private static Scanner input;
public static void main(String[] args) {
input = new Scanner(System.in);
int n = input.nextInt();
ArrayList<Integer> id = new ArrayList<Integer>();
for(int i = 0; i < n; i++) {
int index = input.nextInt();
if(id.contains(index)) {
continue;
}else {
id.add(index);
}
}
for (Integer i : id) {
System.out.print(i + " ");
}
}
}
C題:
C++代碼,是比賽上交源碼所以沒有注釋
#include <bits/stdc++.h>
using namespace std;
struct student{
string name;
int num;
int totalScore;
}s[105];
bool cmp(student m, student n){
if(m.totalScore == n.totalScore){
return m.num < n.num;
}
return m.totalScore > n.totalScore;
}
int main(){
int n; //學生數
scanf("%d", &n);
int scoreOne, scoreTwo;
for(int i = 0; i < n; i++){
cin >> s[i].name >> scoreOne >> scoreTwo;
s[i].num = i;
s[i].totalScore = (int)round(0.4 * scoreOne + 0.6 * ceil((sqrt(scoreTwo) * 10)));
}
sort(s, s + n, cmp);
for(int i = 0; i < n; i++){
cout << s[i].name << " " << (s[i].totalScore) << endl;
}
return 0;
}
java的代碼用上了Arrays包,Comparator包。
不熟悉的話就寫着很麻煩……
import java.util.Arrays;
import java.util.Comparator;
import java.util.Scanner;
public class Main {
static Scanner input;
public static final int N = 105;
static class Student{
public String name = "";
public int id = 0;
public int score = 0;
}
static class cmp implements Comparator<Student>{
//重寫接口中的方法
public int compare(Student s1, Student s2) {
//我們希望達到的要求是 按成績降序排列
//成績相等的情況下 先輸入的排前面
/**
* 背下來叭,我一下子也沒繞清楚
* 如果要按照升序排序 則o1 小於o2 返回-1(負數) 相等返回0 01大於02返回+1(正數)
* 如果要按照降序排序 則o1 小於o2 返回+1(正數) 相等返回0 01大於02返回-1(負數)
*/
if(s1.score == s2.score) {
//不像C++是返回一個boolean類型了
// return s1.id < s2.id;
if(s1.id < s2.id) {
return -1;
}
return 1;
}else if(s1.score > s2.score) {
return -1;
}else {
return 1;
}
}
}
public static void main(String[] args) {
input = new Scanner(System.in);
//定義一個Student類型的數組
Student[] student = new Student[N];
double score1 = 0, score2 = 0; //平時成績和期末成績
int n = input.nextInt();
for(int i = 0; i < n; i++) {
student[i] = new Student(); //這個地方容易漏
student[i].name = input.next();
student[i].id = i;
score1 = input.nextDouble();
score2 = input.nextDouble();
score2 = (int)Math.ceil((Math.sqrt(score2) * 10));
student[i].score = (int) Math.round(0.4 * score1 + 0.6 * score2);
}
//用四個參數的
//1.需要排序的數組 2.起始位置 3.結束位置 4.排序規則
//注意靜態不能調用非靜態 所以寫的內部類都要為靜態的
Arrays.sort(student, 0, n, new cmp());
for (int i = 0; i < n; i++) {
System.out.println(student[i].name + " " + student[i].score);
}
}
}
D題:
C++的代碼,也是純純暴力……
巧方法應該是用map,鍵值對,但是我不會doge
#include <bits/stdc++.h>
using namespace std;
const int N = 105;
string que[N];
string ans[N];
int main(){
int n, q; //題庫的題目數量和試卷上的題目數量
string qus, a, b, c, d;
int qusNum;
scanf("%d%d", &n, &q);
for(int i = 0; i < n; i++){
cin >> que[i] >> ans[i];
}
for(int i = 0; i < q; i++){
cin >> qus >> a >> b >> c >> d;
//找到題庫里該題目的題號
for(int j = 0; j < n; j++){
if(qus == que[j]){
qusNum = j;
break;
}
}
if(a == ans[qusNum]){
puts("A");
}
if(b == ans[qusNum]){
puts("B");
}
if(c == ans[qusNum]){
puts("C");
}
if(d == ans[qusNum]){
puts("D");
}
}
return 0;
}
java代碼,和C++的代碼思維沒有區別,就是注意equals方法就ok
import java.util.Arrays;
import java.util.Comparator;
import java.util.Scanner;
public class Main {
static Scanner input;
public static final int N = 105;
public static void main(String[] args) {
input = new Scanner(System.in);
//不會鍵值對,所以還是開兩個數組叭
String[] qus = new String[N];
String[] ans = new String[N];
String index, a, b, c, d;
int qusNum = 0;
int n = input.nextInt();
int q = input.nextInt();
for(int i = 0; i < n; i++) {
qus[i] = input.next();
ans[i] = input.next();
}
for (int i = 0; i < q; i++) {
index = input.next();
a = input.next();
b = input.next();
c = input.next();
d = input.next();
for(int j = 0; j < n; j++) {
//如果我沒記錯的話,equals里面最好放保證有值的,不然有可能出問題
if(qus[j].equals(index)) {
qusNum = j;
}
}
if(ans[qusNum].equals(a)) {
System.out.println("A");
}
if(ans[qusNum].equals(b)) {
System.out.println("B");
}
if(ans[qusNum].equals(c)) {
System.out.println("C");
}
if(ans[qusNum].equals(d)) {
System.out.println("D");
}
}
}
}
E題:
C++的代碼,這里和直播的講解代碼不一樣,那個死循環里的代碼順序需要調換一下
#include <bits/stdc++.h>
using namespace std;
const int N = 1000010;
//標記數組用bool省空間~
int student[N];
int main(){
int n, m, k;
scanf("%d%d%d", &n, &m, &k);
int index = 0, ans = 0;;
//置0一下,怕了
memset(student, 0, sizeof(student));
//循環第二行輸入的數據
//每輸入一個數據就判斷這位同學一直傳到哪個拿過花的同學
//因為只要是拿過花的同學都判斷了他往后傳的可能循環
//所以只要傳到了拿過花的就不用再判斷的了
for(int i = 0; i < m; i++){
scanf("%d", &index);
if(student[index]){
//如果為1代表這名同學是拿過花的了
continue;
}
//進入這里了的肯定代表這名同學沒拿過花
//先把這名同學置為1
student[index] = 1;
while(1){
//做個死循環,直到檢查了哪個同學是拿過了花
student[index] = 1;
index += k;
index %= n;
//不知道這兩種寫法誰效率更高
// index = (index + k) % n;
if(student[index]){
break;
}
}
}
//遍歷沒拿過花的同學
for(int i = 0; i < n; i++){
if(student[i] == 0){
ans++;
}
}
printf("%d", ans);
return 0;
}
java代碼
在理解題目的基礎上,一定要搞清楚代碼順序ojz
我寫着寫着又分不清是先判斷退出還是先賦新值還是先給標志數組置1了……
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
final int N = 1000005;
//true代表該名同學拿過花
//就不置false了
boolean student[] = new boolean[N];
int n = input.nextInt();
int m = input.nextInt();
int k = input.nextInt();
int ans = 0;
int index = 0;
for(int i = 0; i < m; i++) {
index = input.nextInt();
if(student[index]) {
continue;
}
//先把該名同學置為true
student[index] = true;
//做個死循環判斷傳給哪些同學
while(true) {
student[index] = true;
index += k;
index %= n;
if(student[index]) {
break;
}
}
}
for(int i = 0; i < n; i++) {
if(student[i]) {
continue;
}
ans++;
}
System.out.println(ans);
}
}