(希望大家不要Copy)
解决RE的方法:
防止segment fault:一些开的很大的数组,应设置为全局变量
如果程序过不了,尝试更改变量作用域等等…
题目描述
输入一个不小于 100100 且小于 10001000,同时包括小数点后一位的一个浮点数,例如 123.4123.4 ,要求把这个数字翻转过来,变成 4.3214.321 并输出。
输入格式
一行一个浮点数
输出格式
一行一个浮点数
此代码未过关,修改中:
#include
int Strlen(char str[]);
void StrReverse(char str[]);
//这里不需要考虑传入二级指针......
int main(){
char str[32];
fgets(str,32,stdin);
StrReverse(str);
printf("%s",str);
}
int Strlen(char str[]){
int i=0;
while(str[i]!='\0')
i++;
return i;
}
void StrReverse(char str[]){
int length=Strlen(str);
//记录这个翻转字符串的关键算法
char *p=str;
char *q=str+length-1;
char t;
int i;
for(i=0;i<length/2;i++){
t=*p;
*p=*q;
*q=t;
//不需要考虑二级指针,只要这里用*p和*q就能改变原字符数组了
p++;
q--;
}
}
过关代码:
#include
#include
int main(void)
{
char str[32],*p,*q,t;
int len;
scanf("%31s",str);
len = strlen(str);
p=str,q=str+len-1;
for(;p<q;p++,q--){
t=*p;
*p=*q;
*q=t;
}
puts(str);
return 0;
}
题目背景
众所周知,一场考试需要一道签到题。
题目描述
给定 n,mn,m,求有多少个正整数 xx,使得 x^m\le nx
m
≤n。
输入格式
一行两个正整数 n,mn,m。
输出格式
一个整数表示正整数 xx 的个数。
#include
#include
int main(void){
int m,n,x=0;
scanf("%d %d",&n,&m);
while(pow(x,m)<=n)
x++;
//注意用pow函数,以及关注此处写法
printf("%d",x-1);
return 0;
}
题目描述
津津上初中了。妈妈认为津津应该更加用功学习,所以津津除了上学之外,还要参加妈妈为她报名的各科复习班。另外每周妈妈还会送她去学习朗诵、舞蹈和钢琴。但是津津如果一天上课超过八个小时就会不高兴,而且上得越久就会越不高兴。假设津津不会因为其它事不高兴,并且她的不高兴不会持续到第二天。请你帮忙检查一下津津下周的日程安排,看看下周她会不会不高兴;如果会的话,哪天最不高兴。
输入格式
输入包括77行数据,分别表示周一到周日的日程安排。每行包括两个小于1010的非负整数,用空格隔开,分别表示津津在学校上课的时间和妈妈安排她上课的时间。
输出格式
一个数字。如果不会不高兴则输出00,如果会则输出最不高兴的是周几(用1, 2, 3, 4, 5, 6, 71,2,3,4,5,6,7分别表示周一,周二,周三,周四,周五,周六,周日)。如果有两天或两天以上不高兴的程度相当,则输出时间最靠前的一天。
#include
int main(){
int i,j,k,n;
int a,b;
int sum[7];
int max;
for(i=0;i<7;i++){
//无需用到二维数组
scanf("%d %d",&a,&b);
sum[i]=a+b;
}
for(k=0,n=1;n<7;){
//这里比较的过程,和选择排序一样
if(sum[k]>=sum[n]){
max=k;
n++;
}
else{
max=n;
k=n;
n++;
}
}
printf("%d",max+1);
return 0;
}
自己去洛谷看题
#include
#include
int main(){
int i=0,sum=0,n=1,ans=0;
char str[1024]={
0};
scanf("%s",str);
int len=strlen(str);
for(i=0;i<11;i++){
if(str[i]!='-'){
sum+=(str[i]-'0')*n;
n++;
}
else continue;
}
ans=sum%11;
if(ans!=10){
if(ans==str[12]-'0') printf("Right");
else{
char num[4]={
0};
char newstr[1024]={
0};
char *p1=str,*p2=num;
sprintf(num,"%d",ans);
for(i=0;i<len-1;i++)
newstr[i]=str[i];
strcat(newstr,num);
printf("%s",newstr);
}
}
else{
if(str[12]=='X') printf("Right");
else{
char alpha[4]="X";
char newstr[1024]={
0};
char *p1=str,*p2=alpha;
for(i=0;i<len-1;i++)
newstr[i]=str[i];
strcat(newstr,alpha);
printf("%s",newstr);
}
}
return 0;
}
题目描述
试计算在区间 11 到 nn的所有整数中,数字x(0 ≤ x ≤ 9)x(0≤x≤9)共出现了多少次?例如,在 11到1111中,即在 1,2,3,4,5,6,7,8,9,10,111,2,3,4,5,6,7,8,9,10,11 中,数字 11 出现了 44 次。
输入格式
22个整数n,xn,x,之间用一个空格隔开。
输出格式
11个整数,表示xx出现的次数。
#include
#include
int main(){
int n,x;
scanf("%d %d",&n,&x);
int i,j,count=0;
char str[102400];
for(i=1;i<=n;i++){
//itoa(i,str,10);
//在洛谷不支持
sprintf(str,"%d",i);
//将数字转化成字符串存入str
j=0;
while(str[j]){
if((str[j]-48)==x)
count++;
j++;
}
}
printf("%d",count);
return 0;
}
题目描述
津津的零花钱一直都是自己管理。每个月的月初妈妈给津津300300元钱,津津会预算这个月的花销,并且总能做到实际花销和预算的相同。
为了让津津学习如何储蓄,妈妈提出,津津可以随时把整百的钱存在她那里,到了年末她会加上20%20%还给津津。因此津津制定了一个储蓄计划:每个月的月初,在得到妈妈给的零花钱后,如果她预计到这个月的月末手中还会有多于100100元或恰好100100元,她就会把整百的钱存在妈妈那里,剩余的钱留在自己手中。
例如1111月初津津手中还有8383元,妈妈给了津津300300元。津津预计1111月的花销是180180元,那么她就会在妈妈那里存200200元,自己留下183183元。到了1111月月末,津津手中会剩下33元钱。
津津发现这个储蓄计划的主要风险是,存在妈妈那里的钱在年末之前不能取出。有可能在某个月的月初,津津手中的钱加上这个月妈妈给的钱,不够这个月的原定预算。如果出现这种情况,津津将不得不在这个月省吃俭用,压缩预算。
现在请你根据2004年1月到12月每个月津津的预算,判断会不会出现这种情况。如果不会,计算到2004年年末,妈妈将津津平常存的钱加上20%还给津津之后,津津手中会有多少钱。
输入格式
1212行数据,每行包含一个小于350350的非负整数,分别表示11月到1212月津津的预算。
输出格式
一个整数。如果储蓄计划实施过程中出现某个月钱不够用的情况,输出-X−X,XX表示出现这种情况的第一个月;否则输出到20042004年年末津津手中会有多少钱。
注意,洛谷不需要进行文件输入输出,而是标准输入输出。
#include
int main(){
int i,expense,locMoney=0,num=0;
for(i=1;i<=12;i++)
{
scanf("%d",&expense);
locMoney=locMoney-expense+300;
if(locMoney<0)
{
printf("-%d",i);
return 0;
}
else num+=locMoney/100,locMoney%=100;
//除法和取模值得学习
}
printf("%d",120*num+locMoney);
return 0;
}
【题目描述】
幻方是一种很神奇的 N*NN∗N 矩阵:它由数字 1,2,3,\cdots \cdots ,N \times N1,2,3,⋯⋯,N×N 构成,且每行、每列及两条对角线上的数字之和都相同。
当 NN 为奇数时,我们可以通过下方法构建一个幻方:
首先将 11 写在第一行的中间。
之后,按如下方式从小到大依次填写每个数 K (K=2,3,\cdots,N \times N)K(K=2,3,⋯,N×N) :
若 (K-1)(K−1) 在第一行但不在最后一列,则将 KK 填在最后一行, (K-1)(K−1) 所在列的右一列;
若 (K-1)(K−1) 在最后一列但不在第一行,则将 KK 填在第一列, (K-1)(K−1) 所在行的上一行;
若 (K-1)(K−1) 在第一行最后一列,则将 KK 填在 (K-1)(K−1) 的正下方;
若 (K-1)(K−1) 既不在第一行,也不在最后一列,如果 (K-1)(K−1) 的右上方还未填数,则将 KK 填在 (K-1)(K−1) 的右上方,否则将 KK 填在 (K-1)(K−1) 的正下方。
现给定 NN ,请按上述方法构造 N \times NN×N 的幻方。
【输入格式】
一个正整数 NN ,即幻方的大小。
【输出格式】
共 NN 行 ,每行 NN 个整数,即按上述方法构造出的 N \times NN×N 的幻方,相邻两个整数之间用单空格隔开。
#include
int main(){
int n=0,i=0,j=0,k=0,key=1,mid=0;
int c=0,r=0;
scanf("%d",&n);
int arr[128][128];
int num[100000]={
0};
for(k=1;k<100000;k++)
num[k]=key++;
//将0到99999都存入数组 num
mid=(n-1)/2;
arr[0][mid]=1;
r=0,c=mid;
//表示出上一个数的位置,0表示第一行或第一列
//此处初始化,1的位置在第一行中间
for(k=2;num[k]<=n*n;k++){
if(r==0&&c!=n-1){
arr[n-1][c+1]=num[k];
r=n-1;
c=c+1;
}
else if(r!=0&&c==n-1){
arr[r-1][0]=num[k];
r=r-1;
c=0;
}
else if(r==0&&c==n-1){
arr[1][n-1]=num[k];
r=1;
c=n-1;
}
else if(r!=0&&c!=n-1){
if(!arr[r-1][c+1]){
arr[r-1][c+1]=num[k];
r=r-1;
c=c+1;
}
else{
arr[r+1][c]=num[k];
r=r+1;
}
}
}
for(i=0;i<n;i++)
for(j=0;j<n;j++)
printf("%d%c", arr[i][j], (j + 1 == n) ? '\n' : ' ');
return 0;
}
题目描述
小 A 有一个质数口袋,里面可以装各个质数。他从 22 开始,依次判断各个自然数是不是质数,如果是质数就会把这个数字装入口袋。口袋的负载量就是口袋里的所有数字之和。但是口袋的承重量有限,不能装得下总和超过 L的质数。给出 L,请问口袋里能装下几个质数?将这些质数从小往大输出,然后输出最多能装下的质数个数,所有数字之间有一空行。
输入格式
一行一个正整数 L。
输出格式
将这些质数从小往大输出,然后输出最多能装下的质数个数,所有数字之间有一空行。
#include
int main(){
int prime[100001]={
0};
int limit=0,sum=0,count=0,x=0,y=0,k=0,i=0;
scanf("%d",&limit);
if(limit==1) limit=0;
for(x=2;x<=100001;x++){
for(y=2;y<=50001;y++){
if(x%y==0) count++;
if(count>1||x<y) break;
}
if(count==1) {
prime[k++]=x;
sum+=x;
if(sum>limit){
sum-=x;
prime[--k]=0;
break;
//由于多计了一个数,在这里被卡了一会
}
}
count=0;
}
for(i=0;i<k;i++)
printf("%d\n",prime[i]);
printf("%d",k);
return 0;
}
题目描述
若一个数(首位不为零)从左向右读与从右向左读都一样,我们就将其称之为回文数。
例如:给定一个十进制数 5656,将 5656 加 6565(即把 5656 从右向左读),得到 121121 是一个回文数。
又如:对于十进制数 8787:
STEP1:87+78=16587+78=165
STEP2:165+561=726165+561=726
STEP3:726+627=1353726+627=1353
STEP4:1353+3531=48841353+3531=4884
在这里的一步是指进行了一次 NN 进制的加法,上例最少用了 44 步得到回文数 48844884。
写一个程序,给定一个 NN(2 \le N \le 102≤N≤10 或 N=16N=16)进制数 MM(100100 位之内),求最少经过几步可以得到回文数。如果在 3030 步以内(包含 3030 步)不可能得到回文数,则输出 Impossible!。
输入格式
两行,分别是 NN,MM。
输出格式
如果能在 3030 步以内得到回文数,输出格式形如 STEP=ans,其中 ansans 为最少得到回文数的步数。
否则输出 Impossible!。
函数修改实参:先声明一个指针(假设int p=&num)指向要修改的数,然后把指针传入函数,在函数内,对p进行操作,就可以修改num的值
#include
#include
int arr[1000001]={
0},revarr[1000001]={
0};
char str[1000001]={
0};
void GJAdd(int arr[],int revarr[],int *plen,int n){
//高精度,注意函数修改实参
int i=0;
for(i=0;i<=*plen;i++){
arr[i]+=revarr[i];
arr[i+1]+=arr[i]/n;
arr[i]%=n;
}
if(arr[*plen+1]>0) (*plen)++;
return;
}
void Rev(int arr[],int revarr[],int len){
//逆序
int i=0,j=0;
for(i=len;i>0;i--)
revarr[++j]=arr[i];
return;
}
int Judge(int arr[],int len){
//判断是否回文
int ln=len,i=1,j=len;
while(ln/2){
ln--;
if(arr[i++]!=arr[j--])
return 0;
}
return 1;
}
void Init(){
//初始化
int j=0,i=0;
for(i=strlen(str)-1;i>=0;i--){
if(str[i]>='0'&&str[i]<='9')
arr[++j]=str[i]-'0';
else
arr[++j]=str[i]-'A'+10;
}
return;
}
int main(){
int ans=0,n=0,num=0,i=0;
scanf("%d\n",&n);
scanf("%s",str);
//洛谷不要用getchar()
int len=strlen(str);
int *plen=&len;
Init();
while(!Judge(arr,len)&&ans<30){
//竟然忘了判断ans<30,我大意了啊
ans++;
Rev(arr,revarr,len);
GJAdd(arr,revarr,plen,n);
}
if(ans<30)
printf("STEP=%d",ans);
else printf("Impossible!");
return 0;
}
原题略,直接去洛谷搜题号吧
#include
#include
#include
int p1=0,p2=0,p3=0;
char str[1024]={
0};
int PrintStr(char l,char r){
char i=0;
int n=0;
if(l>=r||(isdigit(l)&&isalpha(r))||(isdigit(r)&&isalpha(l)))
printf("-");
else if(l+1==r) return 0;
else{
if(isalpha(l)){
if(p1==1){
//变小写
l=tolower(l);
r=tolower(r);
}
else if(p1==2){
//变大写
l=toupper(l);
r=toupper(r);
}
}
if(p3==1){
//正序
for(i=l+1;i<r;i++){
for(n=0;n<p2;n++)
//输出p2个
printf("%c",(p1==3)?'*':i);
}
}
else if(p3==2){
//逆序
for(i=r-1;i>l;i--)
//又把l和1看错了,我勒个去......
for(n=0;n<p2;n++)
//输出p2个
printf("%c",(p1==3)?'*':i);
}
}
}
int main(){
scanf("%d%d%d",&p1,&p2,&p3);
scanf("%s",str);
char l=0;
int i=0,start=0,len=strlen(str);
//判断开头的'-'
for(i=0;i<len;i++){
if(str[i]=='-') printf("-");
else{
start=i;
break;
}
}
//对于剩余字符
for(i=start;i<len;i++){
if(str[i]!='-') printf("%c",str[i]);
else if(i+1==len||(i+1!=len&&str[i+1]=='-')||l=='-') printf("-");
else PrintStr(l,str[i+1]);
l=str[i];
}
return 0;
}
原题去洛谷
#include
#include
#include
int main(){
char key[101]={
0},psg[1001]={
0},newpsg[1001]={
0};
int newkey[101]={
0};
int i=0;
scanf("%s",key);
scanf("%s",psg);
int len1=strlen(key),len2=strlen(psg);
for(i=0;i<len1;i++){
key[i]=tolower(key[i]);
newkey[i]=key[i]-'a';
}
for(i=0;i<len2;i++)
if(psg[i]>='a'&&psg[i]<='z'&&psg[i]-newkey[i%len1]>='a')
newpsg[i]=psg[i]-newkey[i%len1];
else if(psg[i]>='a'&&psg[i]<='z'&&psg[i]-newkey[i%len1]<'a')
newpsg[i]=psg[i]-newkey[i%len1]+26;
else if(psg[i]>='A'&&psg[i]<='Z'&&psg[i]-newkey[i%len1]>='A')
newpsg[i]=psg[i]-newkey[i%len1];
else newpsg[i]=psg[i]-newkey[i%len1]+26;
printf("%s",newpsg);
return 0;
}
一开始会错意,把题目倒过来了,违背了原题初衷:
#include
#include
//题目要求它的逆过程
int BubbleSort(char str[1024][1024],int len)
{
int i=0,j=0;
for(i=1;i<len;i++)
for(j=0;j<len-i;j++)
if(str[j][0]>str[j+1][0]){
char tempstr[1024]={
0};
strcpy(tempstr,str[j]);
strcpy(str[j],str[j+1]);
strcpy(str[j+1],tempstr);
//在二维数组中交换字符串的方式
}
return 0;
}
int main(){
int len=0,i=0,j=0,k=0,p=0,n=0;
scanf("%d",&len);
char str[1024][1024]={
0};
scanf("%s",str[0]);
scanf("%d",&p);
for(i=1;i<len;i++){
char tmpstr[1024]={
0};
char *p=&str[0][i];
strcpy(tmpstr,p);
int tmplen=strlen(tmpstr);
for(j=0;j<len-tmplen;j++)
tmpstr[tmplen+j]=str[0][j];
strcpy(str[i],tmpstr);
}
BubbleSort(str,len);
char ans[1024]={
0};
for(k=0;k<len;k++)
ans[k]=str[k][p-1];
for(k=0;k<len;k++)
printf("%s\n",str[k]);
return 0;
}
题目正确的代码:
(因为偷懒,暂时没看代码的逻辑)
#include
char s[1000001]={
0},ans[1000001]={
0};
int n=0,p=0,i=0;
int a[26]={
0},l[26]={
0},r[26]={
0};
//不知道为什么,设置成全局变量后才能通过洛谷评测
int main(){
scanf("%d%s%d",&n,s+1,&p);
for(i=1;i<=n;i++) a[s[i]-'a']++;
for(i=0;i<26;i++){
l[i]=r[i-1]+1;
r[i]=l[i]+a[i]-1;
}
int now=l[s[p]-'a'];
int tot=0;
while(tot<n){
ans[tot]=s[now];
now=r[s[now]-'a']--;
tot++;
}
for(i=n-1;i>=0;i--) printf("%c",ans[i]);
return 0;
}
题目描述
明明想在学校中请一些同学一起做一项问卷调查,为了实验的客观性,他先用计算机生成了NN个11到10001000之间的随机整数(N≤100)(N≤100),对于其中重复的数字,只保留一个,把其余相同的数去掉,不同的数对应着不同的学生的学号。然后再把这些数从小到大排序,按照排好的顺序去找同学做调查。请你协助明明完成“去重”与“排序”的工作。
输入格式
输入有两行,第11行为11个正整数,表示所生成的随机数的个数NN
第22行有NN个用空格隔开的正整数,为所产生的随机数。
输出格式
输出也是两行,第11行为11个正整数MM,表示不相同的随机数的个数。
第22行为MM个用空格隔开的正整数,为从小到大排好序的不相同的随机数。
方法一:分别写出去重函数和qsort排序
#include
#include
#include
int arraylen(int array[]){
int i=0;
for(i=0;array[i];i++);
return i;
}
int RemoveDuplicate(int array[],int newarr[]){
int r=0,w=0,i=0,j=0,len=0,count=0;
len=arraylen(array);
for(r=w=0;r<len;r++){
if(array[r]){
array[w++]=array[r];
for(i=r+1;i<len;i++){
if(array[r]==array[i]){
array[i]=0;
count++;
}
}
}
}
for(j=0;j<len-count;j++){
newarr[j]=array[j];
}
return count;
}
int cmp(const void *a, const void *b)
{
return ( *(int*)a - *(int*)b );
}
int sort(int array[],int n){
qsort(array,n, sizeof(int),cmp);
return 0;
}
int main(){
int n=0,i=0,len=0,count=0;
int array[3200];
scanf("%d",&n);
for(i=0;i<n;i++)
scanf("%d",&array[i]);
int newarr[3200];
len=arraylen(array);
count=RemoveDuplicate(array,newarr);
sort(newarr,len-count);
printf("%d\n",len-count);
for(i=0;i<len-count;i++)
printf("%d ",newarr[i]);
return 0;
}
方法二:桶排序(推荐)
桶排序的思路比较简单,不再赘述。
#include
int BucketArr(int arr[],int n){
int i=0,j=0,count=0;
int num[10000]={
0};
for(i=0;i<n;i++){
if(arr[i]&&!num[arr[i]])
//注意此处是num[arr[i]],容易写错
{
num[arr[i]]++;
count++;
}
}
printf("%d\n",count);
for(j=0;j<10000;j++){
if(num[j])
printf("%d ",j);
}
return 0;
}
int main(){
int n=0,i=0;
int arr[10000]={
0};
scanf("%d",&n);
for(i=0;i<n;i++){
scanf("%d",&arr[i]);
}
BucketArr(arr,n);
return 0;
}
题目描述
世博会志愿者的选拔工作正在 A 市如火如荼的进行。为了选拔最合适的人才,AA市对所有报名的选手进行了笔试,笔试分数达到面试分数线的选手方可进入面试。面试分数线根据计划录取人数的150%150%划定,即如果计划录取mm名志愿者,则面试分数线为排名第m \times 150%m×150%(向下取整)名的选手的分数,而最终进入面试的选手为笔试成绩不低于面试分数线的所有选手。
现在就请你编写程序划定面试分数线,并输出所有进入面试的选手的报名号和笔试成绩。
输入格式
第一行,两个整数 n,m(5 ≤ n ≤ 5000,3 ≤ m ≤ n)n,m(5≤n≤5000,3≤m≤n),中间用一个空格隔开,其中nn表示报名参加笔试的选手总数,mm表示计划录取的志愿者人数。输入数据保证 m \times 150%m×150%向下取整后小于等于 nn。
第二行到第 n+1n+1 行,每行包括两个整数,中间用一个空格隔开,分别是选手的报名号 k(1000 ≤ k ≤ 9999)k(1000≤k≤9999)和该选手的笔试成绩s(1 ≤ s ≤ 100)s(1≤s≤100)。数据保证选手的报名号各不相同。
输出格式
第一行,有22个整数,用一个空格隔开,第一个整数表示面试分数线;第二个整数为进入面试的选手的实际人数。
从第二行开始,每行包含22个整数,中间用一个空格隔开,分别表示进入面试的选手的报名号和笔试成绩,按照笔试成绩从高到低输出,如果成绩相同,则按报名号由小到大的顺序输出。
#include
typedef struct stu{
int num;
int mark;
}stu;
void StructSort(stu arr[],int n){
stu temp;
int i=0,j=0;
for(i=1;i<n;i++){
for(j=0;j<n-i;j++){
if(arr[j].mark<arr[j+1].mark){
temp=arr[j];
arr[j]=arr[j+1];
arr[j+1]=temp;
}
else if(arr[j].mark==arr[j+1].mark&&arr[j].num>arr[j+1].num){
temp=arr[j];
arr[j]=arr[j+1];
arr[j+1]=temp;
}
}
}
return;
}
int main(){
int n=0,m=0,M=0,i=0,j=0,markline=0;
//n是选手总数,m是计划录取人数,M是进入面试人数
scanf("%d %d",&n,&m);
stu stus[51200];
for(i=0;i<n;i++)
scanf("%d %d",&stus[i].num,&stus[i].mark);
StructSort(stus,n);
M=m*3/2;
markline=stus[M-1].mark;
for(j=M;j<n;j++)
if(stus[j].mark==markline)
M++;
printf("%d %d\n",markline,M);
for(i=0;i<M;i++)
printf("%d %d\n",stus[i].num,stus[i].mark);
return 0;
}
题目描述
某小学最近得到了一笔赞助,打算拿出其中一部分为学习成绩优秀的前5名学生发奖学金。期末,每个学生都有3门课的成绩:语文、数学、英语。先按总分从高到低排序,如果两个同学总分相同,再按语文成绩从高到低排序,如果两个同学总分和语文成绩都相同,那么规定学号小的同学 排在前面,这样,每个学生的排序是唯一确定的。
任务:先根据输入的3门课的成绩计算总分,然后按上述规则排序,最后按排名顺序输出前五名名学生的学号和总分。注意,在前5名同学中,每个人的奖学金都不相同,因此,你必须严格按上述规则排序。例如,在某个正确答案中,如果前两行的输出数据(每行输出两个数:学号、总分) 是:
77 279279
55 279279
这两行数据的含义是:总分最高的两个同学的学号依次是77号、55号。这两名同学的总分都是 279279 (总分等于输入的语文、数学、英语三科成绩之和) ,但学号为77的学生语文成绩更高一些。如果你的前两名的输出数据是:
55 279279
77 279279
则按输出错误处理,不能得分。
输入格式
共n+1行。
第11行为一个正整数n( \le 300)n(≤300),表示该校参加评选的学生人数。
第22到n+1n+1行,每行有33个用空格隔开的数字,每个数字都在00到100100之间。第jj行的33个数字依次表示学号为j-1j−1的学生的语文、数学、英语的成绩。每个学生的学号按照输入顺序编号为1~n1 n(恰好是输入数据的行号减11)。
所给的数据都是正确的,不必检验。
//感谢 黄小U饮品 修正输入格式
输出格式
共5行,每行是两个用空格隔开的正整数,依次表示前55名学生的学号和总分。
#include
typedef struct stu{
int num;
int Chi;
int math;
int Eng;
int score;
//结构体内的成员不可以初始化为0,会报错
}stu;
int StructSort(stu arr[],int n){
stu temp;
int i=0,j=0;
for(i=1;i<n;i++)
for(j=0;j<n-i;j++)
if(arr[j].score<arr[j+1].score){
temp=arr[j];
arr[j]=arr[j+1];
arr[j+1]=temp;
}
//使用冒泡排序比较总成绩,总成绩相同则比较语文成绩
else if(arr[j].score==arr[j+1].score){
if(arr[j].Chi<arr[j+1].Chi){
temp=arr[j];
arr[j]=arr[j+1];
arr[j+1]=temp;
}
}
}
int main(){
int n=0,i=0,j=0;
stu arr[3200];
//数组开小会RE
scanf("%d",&n);
for(i=0;i<n;i++){
arr[i].num=i+1;
scanf("%d %d %d",&arr[i].Chi,&arr[i].math,&arr[i].Eng);
arr[i].score=arr[i].Chi+arr[i].math+arr[i].Eng;
}
StructSort(arr,n);
for(j=0;j<5;j++)
printf("%d %d\n",arr[j].num,arr[j].score);
return 0;
}
游戏规则含图片,直接附上题目链接:这儿
题目不难,用switch可以少用一些if
#include
int main(){
int n=0,t1=0,t2=0,score1=0,score2=0;
int i=0,j=0,k=0;
int T1[256]={
0};
int T2[256]={
0};
scanf("%d %d %d",&n,&t1,&t2);
for(i=0;i<t1;i++)
scanf("%d",&T1[i]);
for(j=0;j<t2;j++){
scanf("%d",&T2[j]);
}
for(k=0;k<n;k++){
int p=k,q=k;
if(p>=t1) p%=t1;
if(q>=t2) q%=t2;
if(T1[p]==0){
switch(T2[q]){
case 0:break;
case 1:score2++;break;
case 2:score1++;break;
case 3:score1++;break;
case 4:score2++;break;
}
}
else if(T1[p]==1){
switch(T2[q]){
case 0:score1++;break;
case 1:break;
case 2:score2++;break;
case 3:score1++;break;
case 4:score2++;break;
}
}
else if(T1[p]==2){
switch(T2[q]){
case 0:score2++;break;
case 1:score1++;break;
case 2:break;
case 3:score2++;break;
case 4:score1++;break;
}
}
else if(T1[p]==3){
switch(T2[q]){
case 0:score2++;break;
case 1:score2++;break;
case 2:score1++;break;
case 3:break;
case 4:score1++;break;
}
}
else if(T1[p]==4){
switch(T2[q]){
case 0:score1++;break;
case 1:score1++;break;
case 2:score2++;break;
case 3:score2++;break;
case 4:break;
}
}
}
printf("%d %d",score1,score2);
return 0;
}
题目描述
为了准备一个独特的颁奖典礼,组织者在会场的一片矩形区域(可看做是平面直角坐标系的第一象限)铺上一些矩形地毯。一共有 nn 张地毯,编号从 11 到 nn。现在将这些地毯按照编号从小到大的顺序平行于坐标轴先后铺设,后铺的地毯覆盖在前面已经铺好的地毯之上。
地毯铺设完成后,组织者想知道覆盖地面某个点的最上面的那张地毯的编号。注意:在矩形地毯边界和四个顶点上的点也算被地毯覆盖。
输入格式
输入共 n + 2n+2 行。
第一行,一个整数 nn,表示总共有 nn 张地毯。
接下来的 nn 行中,第 i+1i+1 行表示编号 ii 的地毯的信息,包含四个整数 a ,b ,g ,ka,b,g,k,每两个整数之间用一个空格隔开,分别表示铺设地毯的左下角的坐标 (a, b)(a,b) 以及地毯在 xx 轴和 yy 轴方向的长度。
第 n + 2n+2 行包含两个整数 xx 和 yy,表示所求的地面的点的坐标 (x, y)(x,y)。
输出格式
输出共 11 行,一个整数,表示所求的地毯的编号;若此处没有被地毯覆盖则输出 -1。
这估计是我做得最顺的一道题
#include
typedef struct M{
int a;
int b;
int g;
int k;
}M;
int main(){
int n=0,x=0,y=0,i=0,j=0,ans=-1;
M arr[100001];
scanf("%d",&n);
for(i=0;i<n;i++)
scanf("%d %d %d %d",&arr[i].a,&arr[i].b,&arr[i].g,&arr[i].k);
scanf("%d %d",&x,&y);
for(j=0;j<n;j++){
if((arr[j].a<=x&&(arr[j].a+arr[j].g)>=x)&&(arr[j].b<=y&&(arr[j].b+arr[j].k)>=y))
ans=j+1;
}
printf("%d",ans);
return 0;
}
求复习最短时间
该题解已搞懂
#include
int a[5],i,j,k,sum,t,homework[21],dp[2501];
int max(int a,int b){
if(a>=b) return a;
else return b;
}
int main(){
for(i=1;i<=4;i++)
scanf("%d",&a[i]);
for(i=1;i<=4;i++){
sum=0;
for(j=1;j<=a[i];j++){
scanf("%d",&homework[j]);
sum+=homework[j];
//算出总时间
}
for(j=1;j<=a[i];j++)
for(k=sum/2;k>=homework[j];k--)
//01背包
dp[k]=max(dp[k],dp[k-homework[j]]+homework[j]);
t+=sum-dp[sum/2];
for(j=1;j<=sum/2;j++)
dp[j]=0;
}
printf("%d",t);
return 0;
}
题目:kokodayo
#include
int n,k,ans,a[1024];
int isprime(int a){
for(int i=2;i*i<=a;i++)
if(a%i==0) return 0;
return 1;
}
void dfs(int m,int sum,int startx){
if(m==k){
if(isprime(sum)) ans++;
return;
}
for(int i=startx;i<n;i++)
dfs(m+1,sum+a[i],i+1);
return;
/*这里dfs函数执行的过程像是一个n叉树(在纸上画一画就能明白)
*它遍历的范围超过了要找的所有情况的组合
*有些分支可以一直走下去,找到正确的加和
*而有些分支,比如样例的数据:4 3 n\ 3 7 12 19
*第一次进入dfs函数,从for循环的最后一次递归dfs,即dfs(1,a[3],4)
*再进入新的for循环,int i=4,不满足i
}
int main(){
scanf("%d%d",&n,&k);
for(int i=0;i<n;i++) scanf("%d",&a[i]);
dfs(0,0,0);
printf("%d\n",ans);
return 0;
}
题目描述
传说很遥远的藏宝楼顶层藏着诱人的宝藏。小明历尽千辛万苦终于找到传说中的这个藏宝楼,藏宝楼的门口竖着一个木板,上面写有几个大字:寻宝说明书。说明书的内容如下:
藏宝楼共有N+1N+1层,最上面一层是顶层,顶层有一个房间里面藏着宝藏。除了顶层外,藏宝楼另有NN层,每层MM个房间,这MM个房间围成一圈并按逆时针方向依次编号为0,…,M-10,…,M−1。其中一些房间有通往上一层的楼梯,每层楼的楼梯设计可能不同。每个房间里有一个指示牌,指示牌上有一个数字xx,表示从这个房间开始按逆时针方向选择第xx个有楼梯的房间(假定该房间的编号为k),从该房间上楼,上楼后到达上一层的kk号房间。比如当前房间的指示牌上写着22,则按逆时针方向开始尝试,找到第22个有楼梯的房间,从该房间上楼。如果当前房间本身就有楼梯通向上层,该房间作为第一个有楼梯的房间。
寻宝说明书的最后用红色大号字体写着:“寻宝须知:帮助你找到每层上楼房间的指示牌上的数字(即每层第一个进入的房间内指示牌上的数字)总和为打开宝箱的密钥”。
请帮助小明算出这个打开宝箱的密钥。
输入格式
第一行22个整数NN和MM,之间用一个空格隔开。NN表示除了顶层外藏宝楼共NN层楼,MM表示除顶层外每层楼有MM个房间。
接下来N \times MN×M行,每行两个整数,之间用一个空格隔开,每行描述一个房间内的情况,其中第(i-1) \times M+j(i−1)×M+j行表示第ii层j-1j−1号房间的情况(i=1,2,…, Ni=1,2,…,N;j=1,2,…,Mj=1,2,…,M)。第一个整数表示该房间是否有楼梯通往上一层(00表示没有,11表示有),第二个整数表示指示牌上的数字。注意,从jj号房间的楼梯爬到上一层到达的房间一定也是jj号房间。
最后一行,一个整数,表示小明从藏宝楼底层的几号房间进入开始寻宝(注:房间编号从00开始)。
输出格式
一个整数,表示打开宝箱的密钥,这个数可能会很大,请输出对2012320123取模的结果即可。
我的答案,超时:
#include
typedef struct room{
int a;
int b;
}room;
int N=0,M=0,i=0,j=0,k=0,sum=0,ans=0,start=0;
room arr[10001][101];
//开的很大的数组要设置为全局变量,否则会segment fault
int main(){
scanf("%d %d",&N,&M);
for(i=0;i<N;i++)
for(j=0;j<M;j++)
scanf("%d %d",&arr[i][j].a,&arr[i][j].b);
scanf("%d",&start);
for(i=0;i<N;i++){
sum+=arr[i][start].b;
if(i==N-1) break;
int newstart=start;
while(k!=arr[i][start].b){
if(arr[i][newstart].a==1) k++;
if(k!=arr[i][start].b){
newstart++;
newstart%=M;
}
}
start=newstart;
}
ans=sum%20123;
printf("%d",ans);
return 0;
}
正解,可惜我看的不太懂
#include
int n,m,i,j,a[10010][110],num[10010][110],key,location;
int main(){
scanf("%d %d",&n,&m);
for(i=1;i<=n;i++)
for(j=1;j<=m;j++){
scanf("%d%d",&a[i][j],&num[i][j]);
if(a[i][j]) a[i][0]++;
//a[i][0]储存本层有多少楼梯通往上一层
}
scanf("%d",&location);
location+=1;
for(i=1;i<=n;i++){
key+=num[i][location];
int x=num[i][location]%a[i][0]+a[i][0];
//重点
location--;
while(x){
location++;
if(location>m) location=1;//回到第一个
if(a[i][location]) x--;
}
}
printf("%d",key%20123);
return 0;
}
题目描述
最近欢欢看到一本有关火星的书籍,其中她被一个加法运算所困惑,由于她的运算水平有限.她想向你求助,作为一位优秀的程序员,你当然不会拒绝。
输入格式
第一行先输入一个运算的进制N(2<=N<=36),接下来两行为需要进行运算的字符,其中每个字符串的长度不超过200位,其为N进制的数。其中包括0-9及a-z(代表10-35)。
输出格式
在N进制下它们的和
这道题目是典型的高精度,相较于其他几道题
#include
#include
char str1[102400],str2[102400];
int arr1[102400],arr2[102400];
int max(int a,int b){
if(a>=b) return a;
else return b;
}
void Init(char str[],int arr[]){
int j=0,i=0;
for(i=strlen(str)-1;i>=0;i--){
if(str[i]>='0'&&str[i]<='9')
arr[++j]=str[i]-'0';
else
arr[++j]=str[i]-'a'+10;
}
return;
}
void GJAdd(int arr1[],int arr2[],int *plen,int n){
int i=0;
for(i=0;i<=*plen;i++){
arr1[i]+=arr2[i];
arr1[i+1]+=arr1[i]/n;
arr1[i]%=n;
}
if(arr1[*plen+1]>0) (*plen)++;
return;
}
//以上三个函数,我愿称之为高精三剑客
int main(){
int i=0,n=0;
scanf("%d",&n);
scanf("%s %s",str1,str2);
Init(str1,arr1);
Init(str2,arr2);
int len1=strlen(str1);
int len2=strlen(str2);
int len=max(len1,len2);
//注意这一步是必须的,否则会WA
int *plen=&len;
GJAdd(arr1,arr2,plen,n);
for(i=len;i>=1;i--){
if(arr1[i]>=10) printf("%c",arr1[i]+87);
else printf("%c",arr1[i]+48);
}
return 0;
}
题目描述
给一n \times nn×n的字母方阵,内可能蕴含多个“yizhong”单词。单词在方阵中是沿着同一方向连续摆放的。摆放可沿着 88 个方向的任一方向,同一单词摆放时不再改变方向,单词与单词之间可以交叉,因此有可能共用字母。输出时,将不是单词的字母用*代替,以突出显示单词。
输入格式
第一行输入一个数nn。(7 \le n \le 1007≤n≤100)。
第二行开始输入n \times nn×n的字母矩阵。
输出格式
突出显示单词的n \times nn×n矩阵。
DFS:深度优先搜索
#include
int DFS(int x,int y,int n,char arr[128][128],char newarr[128][128]){
//传参数时,二维数组第一个[]必须传值
int i=0,flag=1,j=1,k=0,count=0;
const int dx[]={
1,1,1,0,0,-1,-1,-1};
const int dy[]={
1,0,-1,1,-1,0,1,-1};
//组合成八个方向的向量
const char str[]="yizhong";
for(i=0;i<8;i++){
for(j=1;j<=6;j++){
int nx=x+j*dx[i];
int ny=y+j*dy[i];
if(nx<0||nx>n||ny<0||ny>n){
break;
//越界
}
if(str[j]!=arr[nx][ny]){
break;
//不匹配
}
count++;
if(count==6){
newarr[x][y]=arr[x][y];
for(k=0;k<=6;k++){
int nx=x+k*dx[i];
int ny=y+k*dy[i];
newarr[nx][ny]=arr[nx][ny];
//将arr内的字符存入newarr
}
count=0;
}
}
}
return 0;
}
int main(){
int n=0,i=0,j=0,p=0,q=0,k=0,l=0,count=0;
char arr[128][128]={
0};
char newarr[128][128]={
0};
scanf("%d",&n);
for(i=0;i<n;i++){
scanf("%s",&arr[i]);
}
for(p=0;p<n;p++){
for(q=0;q<n;q++){
if(arr[p][q]=='y')
DFS(p,q,n,arr,newarr);
}
}
for(k=0;k<n;k++){
for(l=0;l<n;l++){
if(!newarr[k][l]){
if(l+1!=n) printf("*");
else printf("*\n");
//用三目运算符输出'\0',不知为何会输出空格,只能退而求其次
}
else{
if(l+1!=n) printf("%c",arr[k][l]);
else printf("%c\n", arr[k][l]);
}
}
}
return 0;
}
题目描述
由于近期的降雨,雨水汇集在农民约翰的田地不同的地方。我们用一个NxM(1<=N<=100;1<=M<=100)网格图表示。每个网格中有水(‘W’) 或是旱地(’.’)。一个网格与其周围的八个网格相连,而一组相连的网格视为一个水坑。约翰想弄清楚他的田地已经形成了多少水坑。给出约翰田地的示意图,确定当中有多少水坑。
输入格式
第1行:两个空格隔开的整数:N 和 M 第2行到第N+1行:每行M个字符,每个字符是’W’或’.’,它们表示网格图中的一排。字符之间没有空格。
输出格式
一行:水坑的数量
#include
char arr[128][128]={
0};
int flag[128][128]={
0};
//用于判断单元格是否搜索过
const int dx[]={
1,1,1,0,0,-1,-1,-1};
const int dy[]={
1,0,-1,1,-1,0,1,-1};
int DFS(int x,int y){
int i=0,j=0;
flag[x][y]=1;
for(i=0;i<8;i++){
int nx=x+dx[i],ny=y+dy[i];
if(arr[nx][ny]=='W'&&!flag[nx][ny])
DFS(nx,ny);
}
return 0;
}
int main(){
int a=0,b=0,i=0,j=0,k=0,ans=0;
scanf("%d %d",&a,&b);
for(i=0;i<a;i++)
scanf("%s",&arr[i]);
for(j=0;j<a;j++){
for(k=0;k<b;k++){
if(arr[j][k]=='W'&&!flag[j][k]){
DFS(j,k);
ans++;
//ans是answer的缩写
}
}
}
printf("%d",ans);
return 0;
}
这道题还可以用BFS(广度优先搜索),本蒟蒻太懒先搁着…
题目描述
一个N×M的由非负整数构成的数字矩阵,你需要在其中取出若干个数字,使得取出的任意两个数字不相邻(若一个数字在另外一个数字相邻8个格子中的一个即认为这两个数字相邻),求取出数字和最大是多少。
输入格式
第1行有一个正整数T,表示了有T组数据。
对于每一组数据,第一行有两个正整数N和M,表示了数字矩阵为N行M列。
接下来N行,每行M个非负整数,描述了这个数字矩阵。
输出格式
T行,每行一个非负整数,输出所求得的答案。
#include
/*每个数都有取和不取两种选择,
*在main函数中调用dfs函数压入栈底;
*第一次递归入dfs其实就是进了不取这个数的情况;
*当这个递归执行完后,原先接近栈底的函数继续执行,便是取这个数的情况;
*如果它没被标记,就取这个数并且标记它的周围,并且继续递归dfs;
*对于这个数,有时候因为取了它周围数的缘故,导致这它取不了;
*为了让所有数都能被取,一些数标记后应该回溯,去掉标记,
*这样在其他情况中它周围的数就能被取了。
*/
const int d[8][2]={
1,0,-1,0,0,1,0,-1,1,1,-1,1,1,-1,-1,-1};
int t,n,m,s[8][8],mark[8][8],ans,mx;
int max(int a,int b){
if(a>=b) return a;
else return b;
}
void DFS(int x,int y){
//y到边界(y为水平方向)搜索下一行
if(y==m+1){
DFS(x+1,1);
return;
}
//x到边界,搜索结束,刷新最大值
if(x==n+1){
mx=max(ans,mx);
return;
}
//不取此数的情况
DFS(x,y+1);
//取此数的情况
int fx;
if(mark[x][y]==0){
ans+=s[x][y];
for(fx=0;fx<8;fx++)
mark[x+d[fx][0]][y+d[fx][1]]++;
DFS(x,y+1);
//回溯
for(fx=0;fx<8;fx++)
mark[x+d[fx][0]][y+d[fx][1]]--;
ans-=s[x][y];
}
}
int main(){
int i,j;
scanf("%d",&t);
//用while会更加方便
while(t--){
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++)
for(j=1;j<=m;j++)
scanf("%d",&s[i][j]);
mx=0;
DFS(1,1);
printf("%d\n",mx);
}
return 0;
}
题目描述
楼梯有 NN 阶,上楼可以一步上一阶,也可以一步上二阶。
编一个程序,计算共有多少种不同的走法。
输入格式
一个数字,楼梯数。
输出格式
输出走的方式总数。
为什么要用斐波拉契
也可以看这道题下边的题解,有一个题解讲原因讲得不错
#include
int arr[5010][5010]={
0},len=1;
int GJAdd(int k){
int i=0;
for(i=1;i<=len;i++)
arr[k][i]=arr[k-1][i]+arr[k-2][i];
for(i=1;i<=len;i++){
if(arr[k][i]>9){
arr[k][i+1]+=arr[k][i]/10;
//高精度算法
//把高位放在右边
arr[k][i]%=10;
if(arr[k][len+1]>0)len++;
}
}
}
int main(){
int n=0,i=0,j=0,k=0;
arr[0][1]=0;
arr[1][1]=1;
arr[2][1]=2;
scanf("%d",&n);
for(i=3;i<=n;i++)
GJAdd(i);
for(i=len;i>=1;i--){
printf("%d",arr[n][i]);
//输出时要逆序输出
}
return 0;
}
题目背景
无
题目描述
一只蜜蜂在下图所示的数字蜂房上爬动,已知它只能从标号小的蜂房爬到标号大的相邻蜂房,现在问你:蜜蜂从蜂房 m 开始爬到蜂房 n,m
本题和上一题数楼梯是一样的,只是修改了部分变量
#include
int arr[5010][5010]={
0},len=1;
int GJAdd(int k){
int i=0;
for(i=1;i<=len;i++)
arr[k][i]=arr[k-1][i]+arr[k-2][i];
for(i=1;i<=len;i++){
if(arr[k][i]>9){
arr[k][i+1]+=arr[k][i]/10;
//高精度算法
//把高位放在右边
arr[k][i]%=10;
if(arr[k][len+1]>0)len++;
}
}
}
int main(){
int n=0,m=0,i=0,j=0,k=0;
arr[0][1]=0;
arr[1][1]=1;
arr[2][1]=2;
scanf("%d%d",&n,&m);
int div=m-n;
for(i=3;i<=div;i++)
GJAdd(i);
for(i=len;i>=1;i--){
printf("%d",arr[div][i]);
//输出时要逆序输出
}
return 0;
}
题目描述
我们要求找出具有下列性质数的个数(包含输入的正整数 nn)。
先输入一个正整数 nn(n \le 1000n≤1000),然后对此正整数按照如下方法进行处理:
不作任何处理;
在它的左边加上一个正整数,但该正整数不能超过原数的一半;
加上数后,继续按此规则进行处理,直到不能再加正整数为止。
输入格式
11 个正整数 nn(n \le 1000n≤1000)
输出格式
11 个整数,表示具有该性质数的个数。
如果说递归时间复杂度较高,那么递推就是要用一些数学方法,找到规律,降低时间复杂度
#include
int arr[1024];
int main(){
int n,i;
scanf("%d",&n);
arr[1]=1;
/*
设f[i]为初始值为i时的满足条件总数,可得f[i]=f[1]+f[2]+f[3]+...+f[i/2];容易想到f[1]=1;
因为f[i]=f[1]+f[2]+f[3]+...+f[i/2] 所以当i为奇数时f[i]=f[i-1],当i为偶数时f[i]=f[i-1]+f[i/2];
*/
for(i=2;i<=n;i++){
arr[i]=arr[i-1];
if(i%2==0) arr[i]+=arr[i/2];
}
printf("%d",arr[n]);
return 0;
}
题目:kokodayo
看到01背包问题,脑海中一定要有表
若钱充足,办法总数就等于吃这道菜的办法数与不吃这道菜的办法数之和;若不充足,办法总数就只能承袭吃前i-1道菜的办法总数。依次递推,在最后,我们只要输出f[n][m]的值即可。
#include
int n,m;
int arr[101],way[101][10001];
//定义way[i][j]为用前i道菜花光j元钱的方法总数
int main(){
int i,j;
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++) scanf("%d",&arr[i]);
for(i=1;i<=n;i++){
for(j=1;j<=m;j++){
if(j==arr[i]) way[i][j]=way[i-1][j]+1;
else if(j>arr[i]) way[i][j]=way[i-1][j]+way[i-1][j-arr[i]];
else if(j<arr[i]) way[i][j]=way[i-1][j];
}
}
printf("%d",way[n][m]);
return 0;
}
题目在这
#include
#define max 2000000
int n,a[max],m,left,right,l,s,num,mid,ans,i;
int half(int x){
//当前的理想距离是否满足条件,要去右边二分还是去左边二分
s=0,num=0;
//num记录移走石头数目,s记录目前石头距离起点距离
for(i=1;i<=n+1;i++){
if(a[i]-s<x) num++;
else s=a[i];
}
if(num>m) return 0;
//移走石块数>m才能到期望距离,不满足条件
return 1;
}
void bsearch(int left,int right){
while(left<=right){
mid=(left+right)/2;
if(half(mid)){
left=mid+1;
ans=mid;
}
else right=mid-1;
}
}
int main(){
scanf("%d%d%d",&l,&n,&m);
for(i=1;i<=n;i++) scanf("%d",&a[i]);
a[n+1]=l;
left=0,right=l;
bsearch(left,right);
printf("%d",ans);
return 0;
}
题目描述
伐木工人米尔科需要砍倒M米长的木材。这是一个对米尔科来说很容易的工作,因为他有一个漂亮的新伐木机,可以像野火一样砍倒森林。不过,米尔科只被允许砍倒单行树木。
米尔科的伐木机工作过程如下:米尔科设置一个高度参数H(米),伐木机升起一个巨大的锯片到高度H,并锯掉所有的树比H高的部分(当然,树木不高于H米的部分保持不变)。米尔科就行到树木被锯下的部分。
例如,如果一行树的高度分别为20,15,10和17,米尔科把锯片升到15米的高度,切割后树木剩下的高度将是15,15,10和15,而米尔科将从第1棵树得到5米,从第4棵树得到2米,共得到7米木材。
米尔科非常关注生态保护,所以他不会砍掉过多的木材。这正是他为什么尽可能高地设定伐木机锯片的原因。帮助米尔科找到伐木机锯片的最大的整数高度H,使得他能得到木材至少为M米。换句话说,如果再升高1米,则他将得不到M米木材。
输入格式
第1行:2个整数N和M,N表示树木的数量(1<=N<=1000000),M表示需要的木材总长度(1<=M<=2000000000)
第2行:N个整数表示每棵树的高度,值均不超过1000000000。所有木材长度之和大于M,因此必有解。
输出格式
第1行:1个整数,表示砍树的最高高度。
#include
long long n,bz,sum,mid,shortest,longest,trees[1000008];
int max(int a,int b){
if(a>=b) return a;
else return b;
}
int main(){
int i;
scanf("%lld%lld",&n,&bz);
for(i=1;i<=n;i++){
scanf("%lld",&trees[i]);
longest=max(longest,trees[i]);
}
while(shortest<=longest){
sum=0;
mid=(shortest+longest)/2;
for(i=1;i<=n;i++)
if(trees[i]>mid)
sum+=trees[i]-mid;
//高的部分累加
if(sum<bz)
//木材不足
longest=mid-1;
//在左边搜,减小高度增加木材
else
shortest=mid+1;
//在右边搜,增加高度减小木材
}
printf("%lld",shortest-1);
return 0;
}
题目描述
博览馆正在展出由世上最佳的 M 位画家所画的图画。
wangjy想到博览馆去看这几位大师的作品。
可是,那里的博览馆有一个很奇怪的规定,就是在购买门票时必须说明两个数字,
a和b,代表他要看展览中的第 a 幅至第 b 幅画(包含 a 和 b)之间的所有图画,而门票
的价钱就是一张图画一元。
为了看到更多名师的画,wangjy希望入场后可以看到所有名师的图画(至少各一张)。
可是他又想节省金钱。。。
作为wangjy的朋友,他请你写一个程序决定他购买门票时的 a 值和 b 值。
输入格式
第一行是 N 和 M,分别代表博览馆内的图画总数及这些图画是由多少位名师的画
所绘画的。
其后的一行包含 N 个数字,它们都介于 1 和 M 之间,代表该位名师的编号。
输出格式
a和 b(a<=b) 由一个空格符所隔开。
保证有解,如果多解,输出a最小的。
#include
int l = 1,r = 1;
int arr[1000001];
//存放画的序号
int buc[2001];
//每一位画家对应一个桶
int count;
int L,R,M=0xffff;
int main(){
int n,m,i;
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++)
scanf("%d",&arr[i]);
buc[arr[1]]++;
count++;
for(l=1,r=1;l<=n;l++){
buc[arr[l-1]]--;
//左指针向前进一个,原先最开头的画就不看了,对应画家的桶减1
if(buc[arr[l-1]]==0)
//如果从1减到0了,画家总人数少1
count--;
while(count<m&&r<=n){
r++;
//下一次进入while循环的时候,r还保持上一次最后的值,降低了时间复杂度
buc[arr[r]]++;
if(buc[arr[r]]==1)
//桶内从0增到0,画家总人数多1
count++;
}
if(count==m&&r-l+1<M){
//移动左右指针,进入下一轮
M=r-l+1;
//M表示这一轮看了几幅画,如果数量比之前少就更新
L=l;R=r;
}
}
printf("%d %d",L,R);
return 0;
}
【题目描述】
三个整数分别为 A,B,CA,B,C . 这三个数字不会按照这样的顺序给你,但它们始终满足条件: A<B<CA<B<C . 为了看起来更加简洁明了,我们希望你可以按照给定的顺序重新排列它们。
【输入格式】
第一行包含三个正整数 A,B,CA,B,C ,不一定是按这个顺序。这三个数字都小于或等于 100100 。第二行包含三个大写字母 AA 、 BB 和 CC (它们之间没有空格)表示所需的顺序.
【输出格式】
在一行中输出 AA ,BB 和 CC ,用一个 (空格)隔开.
#include
int BubbleSort(int a[],int n)
{
int i,j,t;
for(i=1;i<n;i++)
for(j=0;j<n-i;j++)
if(a[j]>a[j+1]){
t=a[j];
a[j]=a[j+1];
a[j+1]=t;
}
return 0;
}
int main(){
int arr[1024]={
0};
char mark;
int i=0,j=0;
for(i=0;i<3;i++){
scanf("%d",&arr[i]);
}
BubbleSort(arr,3);
getchar();
//去回车
for(j=0;j<4;j++){
//在dev中j<3即可得到正确结果
mark=getchar();
switch(mark){
case 'A':printf("%d ",arr[0]);break;
case 'B':printf("%d ",arr[1]);break;
case 'C':printf("%d ",arr[2]);break;
}
}
return 0;
}