第一周周记
(一)例题记录
1.Strictly Superior
Problem Statement
AtCoder Shop has N products. The price of the i-th product (1≤i≤N) is Pi. The i-th product (1≤i≤N) has Ci functions. The j-th function (1≤j≤Ci) of the i-th product (1≤i≤N) is represented as an integer F i,j between 1 and M, inclusive.Takahashi wonders whether there is a product that is strictly superior to another. If there are i and j (1≤i,j≤N) such that the i-th and j-th products satisfy all of the following conditions,
print Yes; otherwise, print No.Pi ≥Pj.The j-th product has all functions of the i-th product.Pi>Pj,or the j-th product has one or more functions that the i-th product lacks.
Constraints ,2≤N≤100,1≤M≤100,1≤Pi≤10^5(1≤i≤N),1≤Ci≤M (1≤i≤N),1≤Fi,1<F i,2<…<Fi,Ci ≤M (1≤i≤N) All input values are integers.
Input
The input is given from Standard Input in the following format:
N M
P1 C1 F(1,1) F(1,2) … F(1,C1)
P2 C2 F(2,1) F(2,2) … F(2,C2)
…
Pn Cn F(n,1) F(n,2) … F(n,Cn)
Output
printf the answer in a single line.
Sample Input
5 6
10000 2 1 3
15000 3 1 2 4
30000 3 1 3 5
35000 2 1 5
100000 6 1 2 34 5 6
Sample Output
Yes
代码详解
#include<stdio.h>
int main(){
int N, M, i, j, k, T;
scanf("%d %d", &N, &M);
long int P[100], C[100];//原代码写的是 long int P[N],C[N] ,下面的也是如此 这个比较没想通 因为对于一个数组来说 范围大小应该是确定的而不是变化的 因为题目给了N、M的范围 因此我就给他定了N、M最大的范围100
int F[100][100], FP[100][100];
for(i=0;i<N;i++){//给所有数组赋初值为0
P[i] = 0;
C[i] = 0;
for(j=0;j<M;j++){
FP[i][j] = 0;
}
}
for(i=0;i<N;i++){
scanf("%ld %ld", &P[i], &C[i]);//P[i]代表的是价格 C[i]代表的是样品的数量
for(j=0;j<C[i];j++){
F[i][j] = 0;//F[i][j]代表的是每个产品的样品种类 这边用到了一个二维数组
scanf("%d", &F[i][j]);
T = F[i][j]-1;//这边运用了一个打表 将这个样品的款式转为数组下标 比如该样品的种类是3 为第3种样品所归属 那么对应的 FP[2][2](都要减少一位因为是数组)就有值 t在其中就充当了一个转换;
FP[i][T] += 1;
}
}
T = 0;
for(i=0;i<N;i++){//每个产品都依次比较过去
for(k=0;k<N;k++){
T = 0;
if(i==k){
continue;//两个数字相等 那么继续循环
}else if(P[i]<P[k]){
continue;//钱贵 那么继续循环
}else if(P[i]==P[k] && C[i] == C[k]){
continue;//当价钱一样且产品功能一样多 直接继续循环 因为题目上有个严格优于
}
for(j=0;j<M;j++){//当前面三个条件都没成立时 即 k的价格小于i且k的功能多于i 那么我们接下来就判断 是否k的功能包含i的功能
if(FP[i][j] > 0){//当i这边有功能了 去判断是否k也要存在这个功能
if(FP[k][j] < FP[i][j]){
T = 1;
break;
}
}
}
if(T==0){//由于前面直接continue 所以如果想要到这一步一定得做上面的for循环 如果for循环之后t还是等于0 那么就是存在 如果没有 那么继续循环 直到结束 如果还没有 那么输出NO
printf("Yes");
return 0;
}
}
}
printf("No");
return 0;
}
理解
先解释一下这个题目的大致意思 就是让你挑选出有没有一件产品比另外任何一件(只要一件) 既价格低而且产品的功能更多 如果有就输出Yes 否则就输出No;
这个题目一开始自己做的时候执着于先根据样品多少来进行排序,在有序之后去判断是否样品种类多的那一方拥有样品种类少的那一方的全部样品种类,然后我就一直卡在判断的那个方面,之后去搜了,看了这个比较相对好理解,才发现其实这个题目是可以用打表来做的,是一个比较巧妙的方法。
2. sort
给你n个整数,请按从大到小的顺序输出其中前m大的数。
Input
每组测试数据有两行,第一行有两个数n,m(0<n,m<1000000),第二行包含n个各不相同,且都处于区间[-500000,500000]的整数。
Output
对每组测试数据按从大到小的顺序输出前m大的数。
Sample
Input
5 3
3 -35 92 213 -644
Output
213 92 3
代码详解
#include<bits/stdc++.h>
const int N=1e6 + 5;//范围是-500000-500000 这边的思路也是打表 但数组下标没有负数 因此我们巧妙的把它化解为0-1000000 因此我们要定义N的范围为1e6+5;
int a[N];
int main(){
int n,m;
while(~scanf("%d%d",&n,&m)){
for(int i=0;i<n;i++){
int x;
scanf("%d",&x);
a[x+500000]++;
}
int k=0;
for(int i=1000000;i>=0;i--){
if(a[i]){
printf("%d",i-500000);
k++;
if(k==m){
printf("\n");
break;
}
else{
printf(" ");
}
}
}
}
}
理解
这个是我第一次接触打表类的题目,我感觉这个方法对于一些题是一种很巧妙的方法 日后可以多接触这方面的题目
3.faction again
It is easy to see that for every fraction in the form 1/k(k > 0), we can always find two positive integersx and y, x ≥ y, such that:1/k=1/x+1/y; Now our question is: can you write a program that counts how many such pairs of x and y thereare for any given k?
Input
Input contains no more than 100 lines, each giving a value of k (0 < k
≤ 10000).
Output
For each k, output the number of corresponding (x, y) pairs, followed
by a sorted list of the values of x and y, as shown in the sample
output.
Sample Input
2
12
Sample Output
2
1/2 = 1/6 + 1/3
1/2 = 1/4 + 1/4
8
1/12 = 1/156 + 1/13
1/12 = 1/84 +1/14
1/12 = 1/60 + 1/15
1/12 = 1/48 + 1/16
1/12 = 1/36 + 1/18
1/12 =1/30 + 1/20
1/12 = 1/28 + 1/21
1/12 = 1/24 + 1/24
代码详解
#include<bits/stdc++.h>
int main(){
int k;
while(~scanf("%d",&k)){
int ans=0; //定义在里面 因为有不确定的输入个数 每次都要重新刷新 已经上当好几次了
int a[1000]={0};
int b[1000]={0};
for(int y=k+1;y<=2*k;y++){
if((y*k)%(y-k)==0){//判断是否能整除
int x=y*k/(y-k);
a[ans]=x;
b[ans]=y;
ans++;
}
}
printf("%d\n",ans);
for(int i=0;i<ans;i++){
printf("1/%d = 1/%d + 1/%d\n",k,a[i],b[i]);
}
}
return 0;
}
理解
这个题目当时自己写的时候判断整除那个方面想多了 我还去写了个函数定义double x是否和int x差小于1e-6 ;后来发现按照这种方法写的根本写不下去 因此用上面那个(y*k)%(y-k)更为巧妙。
上述就是这周,也就是这两天 觉得比较有意义的三个题目,还有一些稍难题包括昨天比赛的题目以及枚举的后几题都没有时间仔细去探究 下周周记会补上上述内容