nyoj 稍具技巧的题

韩信点兵 nyoj 34

这题可以用中国剩余定理(这个我不会),我用的只是从1到105逐个搜索

#include<iostream>
using namespace std;
int main()
{
	int a,b,c;
	cin>>a>>b>>c;
	int n=(a*70+b*21+c*15)%105;
	if(n>100||n<10) cout<<"No answer"<<endl;
	else cout<<n<<endl;
	return 0;
}
小明的调查作业 nyoj 48
此题根据规模进行,可以开一个a【1005】的数组,每读一个i,

就把a【i】赋值为true,然后遍历输出,重复计算问题,也挺省时间的。

#include<iostream>
#include<cstring>
using namespace std;
int main()
{
    int n, num;
    int count=0;
    int vis[1005];
    cin>>n;
    memset(vis, 0, sizeof(vis));
    while(n--)
    {
              cin>>num;
              if(!vis[num])
              {
                        vis[num]=1;
                        count++;
              }
    }
    cout<<count<<endl;
    for(int i=1;i<=1000;i++)
            if(vis[i])
                        cout<<i<<" ";
    
    cout<<endl;
    return 0;
}

数的长度 nyoj 69

此题有一种很准确的方法叫斯特林(Stirling)公式;

还有一种也能行,不过数太大时就不是非常准确的方法:

for(int i=1;i<=m;i++)
num += log10(i);

就是对每个乘数取对数

#include<iostream>
#include<cmath>
using namespace std;
int main()
{
    int N;
    cin>>N;
    while(N--)
    {
              int m;
              double num = 0.0;
              cin>>m;
              for(int i=1;i<=m;i++)
                      num += log10(i);
              cout<<(int)(num)+1<<endl;
    }
    return 0;
}
房间安排 nyoj 168

用数组a【201】存放第i天中每天需要的房间数,读房间数、天数,然后找出数组中

最大的元素#include<algorithm>
int p = max_element(a, a+200)-a;
cout<<a[p]<<endl;

#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
int a[201];    //第i天的房间数 
int main()
{
    int T;
    cin>>T;
    while(T--)
    {
              memset(a, 0, sizeof(a));
              int N, num, start, day;
              cin>>N;
              while(N--)
              {
                    cin>>num>>start>>day;
                    for(int i=0;i<day;i++)
                            a[start+i] += num;    
              }
              int p = max_element(a, a+200)-a;
              cout<<a[p]<<endl;
    }
    return 0;
}
素数 nyoj 169

主函数部分设计的很巧妙,先近后远,距离相等的话先大后小

#include<iostream>
using namespace std;
bool fan(int a)
{
    bool b=true;
    int i;
    if(a==1)
        b=false;
    else
        for(i=2;i<a;i++)
        {
            if(a%i==0)
            {b=false;break;}
        }
    return b;
}
int main()
{
    int n;
    cin>>n;
    while(n--)
    {
        int m,i;
        cin>>m;
        for(i=0;;i++)
        {
            if(fan(m+i))
            {cout<<m+i<<endl;break;}
            if(fan(m-i))
            {cout<<m-i<<endl;break;}
        }
    }
    return 0;
}      
字母统计 nyoj 241

此题类似重复计数,用一个数组保存,然后用‘a’+index;算是比较巧妙吧

#include<iostream>
#include<cstring>
#include<string>
using namespace std;
int num[26];
int main()
{
    int N;
    string str;
    cin>>N;
    while(N--)
    {
              memset(num, 0, sizeof(num));
              cin>>str;
                      char ch;
                      for(int j=0;j<str.size();j++)
                      {
                              ch = str.at(j);
                              num[(int)(ch-'a')]++;
                      }
                      int max = num[0];
                      int index = 0;
                      for(int i=0;i<26;i++)
                      {
                              if(num[i] > max)
                              {
                                        max = num[i];
                                        index = i;
                              }
                      }
                      ch = 'a' + index;
                      cout<<ch<<endl;
    }
    return 0;
}
16进制的简单运算 nyoj 244

伤心的代码,我用c++写了好长,人家两句读入输出,换一下格式ok

scanf("%x%c%x", &a, &c, &b);
if(c == '+')
printf("%o\n", a+b);
if(c == '-')
printf("%o\n", a-b);

#include<iostream>
#include<string>
using namespace std;
int main()
{
    int N;
    string str;
    cin>>N;
    while(N--)
    {
              cin>>str;
              char ch;
              int num1 = 0;
              int num2 = 0;
              int temp;
              int oper = str.find('+');
              if(oper == -1)
                      oper = str.find('-');
              for(int i=0;i<oper;i++)
              {
                      ch = str.at(i);
                      num1 *= 16;
                      if(ch >= '0' && ch <= '9')
                            temp = ch - '0';
                      else if(ch >= 'a' && ch <= 'f')
                            temp = ch - 'a' + 10;
                      num1 += temp;
              }
              
              cout<<num1<<endl;
              
              for(int i=oper+1;i<str.size();i++)
              {
                      ch = str.at(i);
                      num2 *= 16;
                      if(ch >= '0' && ch <= '9')
                            temp = ch - '0';
                      else if(ch >= 'a' && ch <= 'f')
                            temp = ch - 'a' + 10;
                      num2 += temp;
              }
              
              cout<<num2<<endl;
              
              ch = str.at(oper);
              if(ch == '+')
              {
                    num1 += num2; 
              }
              else if(ch == '-')
              {
                   num1 -= num2;
              }
              cout<<num1<<endl;
              str = "";
              while(num1)
              {
                         str += ('0'+(num1 % 8));
                         num1 /= 8;
              }
              string s(str.rbegin(),str.rend());
              cout << s <<endl;
    }
    return 0;
}
#include<iostream>
#include<cstdio>
using namespace std;
int main()
{
    int N;
    cin>>N;
    while(N--)
    {
              int a, b;
              char c;
              scanf("%x%c%x", &a, &c, &b);
              if(c == '+')
                   printf("%o\n", a+b);
              if(c == '-')
                   printf("%o\n", a-b);
    }
    return 0;
}
荷兰国旗问题 nyoj 268

用三个数分别记下三个字母出现的次数,然后依序输出就行了,他们提供的最优代码也是这样写的

#include<iostream>
#include<string>
using namespace std;
int main()
{
    int T;
    cin>>T;
    while(T--)
    {
              string s1;
              int a=0,b=0,c=0;
              cin>>s1;
              for(int i=0;i<s1.size();i++)
              {
                      if(s1.at(i) == 'R')
                      {
                                  a++;
                      }
                      else if(s1.at(i) == 'W')
                           b++;
                      else
                          c++;
              }
              for(int i=0;i<a;i++)
                      cout<<"R";
              for(int i=0;i<b;i++)
                      cout<<"W";
              for(int i=0;i<c;i++)
                      cout<<"B";
              cout<<endl;
              
    }
    return 0;
}
正三角形的外接圆面积 nyoj 274

看一个叫做“宝”的仁兄的代码,我觉得很好,收集一下:

#include <iostream>
using namespace std;
#define PI 3.1415926
int main()
{
	int m;
	cin>>m;
	while(m--)
	{
		double s,a;
		cin>>a;
		s=PI*a*a/3.0;
		cout.setf(ios_base::fixed);
		cout.precision(2);
		cout<<s<<endl;
	}
	return 0;
} 
算菜价 nyoj 316

还是“宝”兄的代码,不过这次他用了C

#include<stdio.h>
int main()
{
	double a,b,sum=0;
	char c[20];
	while(scanf("%s%lf%lf",c,&a,&b)!=EOF)
	{
		sum=sum+a*b;
	}
	printf("%.1lf\n",sum);
	return 0;
}   
小光棍数 nyoj 458

第一个光棍数是471,第二个是1000+471,第三个是2000+471,总之是1000的整倍数加471(我不会证明。。。。)

#include<iostream>
using namespace std;
int main()
{
    int n;
    cin>>n;
    while(n--)
    {
          long long int m;
          cin>>m;
          cout<<(m-1)*1000+471<<endl;    
    }
    
    return 0;
}
#include<iostream>
#include<cstdio>
using namespace std;
int main()
{
    long long int n, m;
    scanf("%lld", &n);
    while(n--)
    {
              scanf("%lld", &m);
              printf("%lld\n", (m-1)*1000+471);
    }
    return 0;
}

0


你可能感兴趣的:(技巧)