排序,模拟筛选过程
#include<stdio.h>
#include<algorithm>
using namespace std;
int main(){
int m,n,a[100],c,r,i,b,p;
scanf("%d",&p);
while(p--){
n=0;
scanf("%d%d",&r,&m);
for(i=0;i<m;i++)
scanf("%d",&a[i]);
sort(a,a+m);
b=m-1;c=0;
do{
if(a[c]+a[b]>r) b--;
else {c++;b--;}
n++;
if(c==b) n++;
}
while(c!=b&&b+1!=c);
printf("%d\n",n);
}
return 0;
}
NYO
J 448 寻找最大数
法一:去掉m个数
每次寻找剩余0...n-k中第一个递增连续序列,删除首字符
若不存在递增连续序列,删除末尾元素
提示:此处用java或者pascal中的string变量,可去除元素时,更为方便。
如:
193920
m=1 -->93920
m=2 -->9920
m=3 -->992
m=4 -->99
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int main()
{
int ncase;
char s[110], ans[110];
int m, len, sign, max, num;
scanf("%d", &ncase);
while(ncase--)
{
sign = 0;
scanf("%s %d", s, &m);
len = strlen(s);
while(m--)
{
int i,t;
for(i=0;i<len;i++)
{
while(s[i]==0) i++;
t=i+1;
while(s[t]==0) t++;
if(i==len-1) len--;
if(s[i]<s[t]) break;
}
s[i]=0;
}
for(int i = 0; i < len; ++i)
if(s[i]!=0) cout<<s[i];
cout<<endl;
}
return 0;
}
法二:查找n-m 个数
每次查找一定范围内,最大的数。
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int main()
{
int ncase;
char s[110], ans[110];
int m, len, sign, max, num;
scanf("%d", &ncase);
while(ncase--)
{
num = sign = 0;
scanf("%s %d", s, &m);
len = strlen(s);
for(int i = 0; i < len - m; ++i) //找m次最大值
{
max = -1;
for(int j = sign; j <= m + i; ++j) //j的范围不能错~保证位数
{
if(max < s[j] - '0')
{
max = s[j] - '0';
sign = j;
}
}
ans[num++] = s[sign++];
}
for(int i = 0; i < len - m; ++i)
cout<<ans[i] - '0';
cout<<endl;
}
return 0;
}
运行情况:
#include<cstdio>
int main()
{
int facto[9]={1,2,6,24,120,720,5040,40320,362880},sum,i,m;
scanf("%d",&m);
while(m--)
{
scanf("%d",&sum);
for(i=8;i>=0;i--)//n阶乘比前面n-1阶乘和大
if(sum>=facto[i])
sum-=facto[i];
if(!sum) printf("Yes\n");
else printf("No\n");
}
return 0;
}
NYOJ 364 田忌赛马
#include<cstdio>
int main()
{
int facto[9]={1,2,6,24,120,720,5040,40320,362880},sum,i,m;
scanf("%d",&m);
while(m--)
{
scanf("%d",&sum);
for(i=8;i>=0;i--)//n阶乘比前面n-1阶乘和大
if(sum>=facto[i])
sum-=facto[i];
if(!sum) printf("Yes\n");
else printf("No\n");
}
return 0;
}
法一:慢->快
#include<stdio.h>
#include<algorithm>
using namespace std;
int main()
{
int n,i,t[1050],g[1050];
while(~scanf("%d",&n))
{
for(i=0;i<n;i++)
scanf("%d",&t[i]);
for(i=0;i<n;i++)
scanf("%d",&g[i]);
sort(t,t+n);
sort(g,g+n);
int t1=0,g1=0;
int t2=n-1,g2=n-1,tw=0;
while(g1<=g2)
{
if(t[t1]>g[g1]) {
t1++;
g1++;
tw+=200;
}//先比较最慢
else if(t[t2]>g[g2]){
t2--;
g2--;
tw+=200;
}//比较最快
else {
if(t[t1]<g[g2]) tw-=200;
g2--;
t1++;
}
}
printf("%d\n",tw);
}
return 0;
}
法二:快->慢
#include<stdio.h>
#include<algorithm>
using namespace std;
int main()
{
int n,i,t[1050],g[1050];
while(~scanf("%d",&n))
{
for(i=0;i<n;i++)
scanf("%d",&t[i]);
for(i=0;i<n;i++)
scanf("%d",&g[i]);
sort(t,t+n);
sort(g,g+n);
int t1=0,g1=0;
int t2=n-1,g2=n-1,tw=0;
while(g1<=g2)
{
if(t[t1]>g[g1]) {
t1++;
g1++;
tw+=200;
}//先比较最慢
else if(t[t2]>g[g2]){
t2--;
g2--;
tw+=200;
}//比较最快
else {
if(t[t1]<g[g2]) tw-=200;
g2--;
t1++;
}
}
printf("%d\n",tw);
}
return 0;
}
#include<stdio.h>
#include<algorithm>
using namespace std;
bool cmp(int a,int b)
{
return a>b;
}
int main()
{
int n,m,i,a[1050],b[1050];
while(~scanf("%d",&n) )
{
for( i = 0 ; i < n ;++ i)
scanf("%d",&a[i]);
for( i = 0 ; i < n ;++ i)
scanf("%d",&b[i]);
sort(a,a+n,cmp);
sort(b,b+n,cmp);
int a1=0,a2=n-1,tw=0;
int b1=0,b2=n-1;
while(a1 <= a2)
{
if(a[a1] > b[b1]) //首先比较最快的马
{
tw+=200; //若田忌大于国王
a1++; //下一匹马
b1++;
}
else if( a[a2] > b[b2])
{
tw+=200;
--a2;
--b2;
}
else
{
if(a[a2] < b[b1])
tw-=200;
++b1;
--a2;
}
}
printf("%d\n",tw);
}
}
NYOJ 791 Color the fence
#include<stdio.h>
#include<algorithm>
using namespace std;
bool cmp(int a,int b)
{
return a>b;
}
int main()
{
int n,m,i,a[1050],b[1050];
while(~scanf("%d",&n) )
{
for( i = 0 ; i < n ;++ i)
scanf("%d",&a[i]);
for( i = 0 ; i < n ;++ i)
scanf("%d",&b[i]);
sort(a,a+n,cmp);
sort(b,b+n,cmp);
int a1=0,a2=n-1,tw=0;
int b1=0,b2=n-1;
while(a1 <= a2)
{
if(a[a1] > b[b1]) //首先比较最快的马
{
tw+=200; //若田忌大于国王
a1++; //下一匹马
b1++;
}
else if( a[a2] > b[b2])
{
tw+=200;
--a2;
--b2;
}
else
{
if(a[a2] < b[b1])
tw-=200;
++b1;
--a2;
}
}
printf("%d\n",tw);
}
}
#include<stdio.h>
int main()
{
int n,a[10], m;
while(scanf("%d",&n)!=EOF)
{
for (int i = 1; i <= 9; ++i)
{
scanf("%d", &a[i]);
if(i==1) m=a[1];
if (i>1&&a[i] <= m)//记录最小
m = a[i];
}
if (n < m)
{
printf("-1\n");
}
int k = n / m;//只能k次
int t=9;
while(k--)
{
for (int j = t; j >= 1; --j)
{
if (n >= a[j] && (n - a[j]) / m >= k)//k-1,但输出的值较大,总次数不影响
{
printf("%d",j);
n -= a[j];
t=j;
break;
}
}
}
printf("\n");
}
return 0;
}
NYOJ 47 过河问题
#include<stdio.h>
int main()
{
int n,a[10], m;
while(scanf("%d",&n)!=EOF)
{
for (int i = 1; i <= 9; ++i)
{
scanf("%d", &a[i]);
if(i==1) m=a[1];
if (i>1&&a[i] <= m)//记录最小
m = a[i];
}
if (n < m)
{
printf("-1\n");
}
int k = n / m;//只能k次
int t=9;
while(k--)
{
for (int j = t; j >= 1; --j)
{
if (n >= a[j] && (n - a[j]) / m >= k)//k-1,但输出的值较大,总次数不影响
{
printf("%d",j);
n -= a[j];
t=j;
break;
}
}
}
printf("\n");
}
return 0;
}
模拟过河过程即可。
情况:剩余人数k
k>3 min(a[0]+a[k-2]+a[k-1]+a[0],a[k-1]+a[0]+a[1]+a[1])
k=3 a[0]+a[1]+a[2]
k=2 a[1]
k=1 a[0]
#include<iostream>
#include<algorithm>
using namespace std;
int main()
{
int n,m,a[1000],t;
cin >> n;
while(n--)
{
cin >> m;
t=0;
for(int i=0; i<m; i++)
cin >> a[i];
sort(a,a+m);
while(m>3)
{
t+=min(a[0]+a[m-2]+a[m-1]+a[0],a[m-1]+a[0]+a[1]+a[1]);//去2人
m-=2;
}
if(m==3)
t+=a[0]+a[1]+a[2];
else if(m==2)
t+=a[1];
else
t+=a[0];
cout << t << endl;
}
return 0;
}
#include<iostream>
#include<algorithm>
using namespace std;
int main()
{
int n,m,a[1000],t;
cin >> n;
while(n--)
{
cin >> m;
t=0;
for(int i=0; i<m; i++)
cin >> a[i];
sort(a,a+m);
while(m>3)
{
t+=min(a[0]+a[m-2]+a[m-1]+a[0],a[m-1]+a[0]+a[1]+a[1]);//去2人
m-=2;
}
if(m==3)
t+=a[0]+a[1]+a[2];
else if(m==2)
t+=a[1];
else
t+=a[0];
cout << t << endl;
}
return 0;
}