1893: 985的数学难题(运算方式考察)

1893: 985的数学难题

Time Limit: 2 Sec   Memory Limit: 128 MB
Submit: 120   Solved: 21

Submit Status Web Board

Description

985有n个正整数,他想快速知道下面函数的返回值
int a[N+1];
long long Solve() {
    int i, j;
    long long ans = 0;
    for(i = 1; i <= N; i++) {
    for(int j = i + 1; j <= N; j++) {
   ans += a[i] + a[j] + (a[i] ^ a[j]) + (a[i] | a[j]) + (a[i] & a[j]);
}
    }
    return ans;
}
注:^表示异或运算。

Input

第一行输入一个整数t,代表有t组测试数据。
每组数据第一行输入一个整数代表元素个数,接下来一行输入n个正整数a[]。
注:1 <= t <= 30,1 <= n,a[] <= 100000。

Output

一个整数代表最后的返回值ans。

Sample Input

2
1
10
2
1 1

Sample Output

0
4
首先分析所给源代码,其意是让求所给整数两两之和,两两与运算,或运算,异或运算,然后求总和;
对于两两之和,可以用公式,ans=sum*(n-1);
但进行位运算时,则需要将其化为二进制考虑;
奇数二进制最后一位为1,而偶数二进制最后一位为0;
与运算,同一为一,不同为零
或运算,有一为一,无一为零
异或运算,不同为一,相同为零
代码分析
<pre name="code" class="cpp">#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
long long num[1000000];
long long ans;
bool cmp(int a,int b)
{
    return a > b;
}
int main()
{
    long long n;
    int u;
    scanf ("%d",&u);
    while (u--)
    {memset(a,b,sizeof(a));
     scanf("%lld",&n);
        ans = 0;
        for (int i = 1 ; i <= n ; i++)
        {
            scanf ("%d",&num[i]);
            ans += num[i];
        }
        ans *= (n-1);//两两之和最后之和
        sort(num+1,num+1+n,cmp);//所有数字排序
        long long mul = 1;//表示所在位数,结果想加时,保证数的大小不变
        long long ant;//二进制末尾为1的个数 
        while (num[1])
        {
            ant = 0;
            for (int i = 1 ; i <= n ; i++)
            {
                if (num[i] == 0)
                    break;
                if (num[i] & 1)
                    ant++;//判断其二进制最后一位是否为一
                num[i] >>= 1;//将其二进制数右移一位
            }
            ans+=(((ant-1) * ant) >> 1) * mul;	//共有ant个一,对其排列组合	//与运算 
            ans+=((n-ant) * ant + (((ant-1) * ant) >> 1)) * mul;//只要有一结果都为一,有一和没一排列组合,有一排列组合		//或运算 
            ans+=((n-ant) * ant) * mul;		//异或运算 
            mul <<= 1;
        }
        printf ("%lld\n",ans);
    }}


 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
目录 1 课设任务及要求 1 1.1课设任务: 1 1.2创新要求: 1 1.3设计要求 1 2 需求分析 1 2.1 设计背景 1 2.2 开发的技术及功能 2 3 设计思路 2 4 详细设计 4 4.1功能实现: 4 4.4 程序设计过程 5 5 系统调试 5 5.1 运行调试 5 6 参考文献 7 附录 7 1 课设任务及要求 1.1课设任务: 、设计的计算器应用程序可以完成加法、减法、乘法、除法以及取余运算(可以进 行浮点数和负数的运算); 、有求倒数、退格和清零功能。 1.2创新要求: 能进行正切、余弦,以及求平方根、指数 (包括对e)、自然对数运算。 1.3设计要求 设计的计算器应用程序可以完成加法、减法、乘法、除法和取余运算。且有小数点、正 负号、求倒数、退格和清零功能。 课程设计可选用Eclipse、JBuilder、NetBeans等作为开发平台以提高开发效率,通 过资料查阅和学习尽可能熟练掌握其中一种集成开发环境。 认真按时完成课程设计报告,课程设计报告容包括:设计任务与要求、需求分析、 设计思路、详细设计、运行调试与分析讨论和设计体会与小结六个部分。 2 需求分析 2.1 设计背景 设计这个计算器主要是参考Windows操作系统中自带的计算器,由于编者水平和时间的限 制,不能将计算器设计到科学型及其他更复杂的类型,在设计过程中还参考了一些其他 的优秀设计。但本计算器除了常用的加减乘除(可以进行浮点和负数运算)这些基本运 算外,还有求余、求倒、退格、清零,甚至还能进行一些复杂科学的运算,比如余弦( cos)、正切(tan)、指数运算(pow)、自然对数运算(log)、求平方根(sqrt)以 及对e的指数运算(exp),并且还能进行连续运算。总体上说来,本计算器设计简单, 代码很少,程序很小,但功能却很强大,这是同类计算器所不具备的。 2.2 开发的技术及功能 本课程设计是要做一个图形界面的计算器,其界面主要是由swing组件中的控件构成 。程序实现了计算器的基本功能有:加、减、乘、除基本算术运算(可以进行浮点和负 数运算)和sin、cos、tan等三角函数求值运算,同时能进行指数运算和自然对数运算, 还有求倒数、退格和清零功能。 3 设计思路 、本应用程序继承自框架类(JFrame),容器Container c采用BorderLayout边缘布局,将单行文本框加入到"North"区域,包含各种按钮的面板 JPanel p加入到"Center"区域。包含各种按钮的面板JPanel p 采用3行6列的网格布局,然后将数字按钮和运算符按钮以及控制按钮用一个for循环添加 到面板中同时注册按钮事件监听器。如: Button b=new Button(); b.addActionListener(事件监听器); 、事件监听器中的事件处理方法void actionPerformed(ActionEvent evt)完成主要的按钮事件的处理。事件处理分以下几种情况:数字按钮事件("0","1" ,"2"…"8","9")、运算符按钮事件("+","-","*","/","%")、正负号按钮事件 ("+/- ")、小数点按钮事件(".")、等号按钮事件("=")、求倒按钮事件("求倒")、退 格按钮事件("退格")、清除按钮事件("C") 、正切(tan)、余弦(cos),以及求平方根(sqrt)、指数 (pow)、对e的指数(exp)、对数运算(log)。 、在事件处理,触发按钮事件时,先判断是或是数字是或是"- /+"是或是".",是的话就将负号"-" 、数字、小数点"."分别写入文本框并存放在sum中,然后判断是或是"退格"、"求倒"等 ,是的话进行相应的处理,都不是的话则跳到doOperation()执行运算同时将运算符存放 在preOperater中。触发按钮事件时,要进一步分析,是重新开始计算时触发的按钮事件 还是计算中间触发的按钮事件。 、计算器完成的是一个数学表达式,如:3+2,所以可以采用一个数组来存储数字或字 符,如3,+,2分别存储在数组中,最后运算时,可以一一取出来进行运算。 、利用按钮设计计算器的各个运算符和操作符,通过按钮的事件处理实现按钮计算功能 。 、利用文本框显示操作数和运算结果。 4 详细设计 4.1功能实现: 加减乘除求余以及指数运算 其他运算 、求平方根 、对数运算 、余弦运算 、正切运算 、e的指数运算 、倒数运算 主要方法说明 public cos(double x) //求x的余弦函数 public tan (double x) //求x的正切函数 public sqrt(double x) //求x的平方根 public log (double x) //求x的自然对数运算

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值