HDU1719:Friend

本文介绍了一种基于数学原理的朋友数判定方法。通过递归定义朋友数,并利用数学转换简化判断过程,最终通过检查特定因子来高效判断一个整数是否为朋友数。
Problem Description
Friend number are defined recursively as follows.
(1) numbers 1 and 2 are friend number;
(2) if a and b are friend numbers, so is ab+a+b;
(3) only the numbers defined in (1) and (2) are friend number.
Now your task is to judge whether an integer is a friend number.
 

Input
There are several lines in input, each line has a nunnegative integer a, 0<=a<=2^30.
 

Output
For the number a on each line of the input, if a is a friend number, output “YES!”, otherwise output “NO!”.
 

Sample Input
3 13121 12131
 

Sample Output
YES! YES! NO!
 


 

这道题就是以道纯数学题,我记得第一次看到这道题还是在刚刚搞ACM不久的时候,当时硬是没有想出解决的方法

直到昨天训练赛的时候又出了这道题,仍然是没有弄出来,果然我的数学思维还是不行啊,在看了别人的题解之后,终于算是看懂意思了,在此有必要解释一下

 

首先,原式ab+a+b = ab+a+b+1-1 = (a+1)*(b+1)-1

令a = (a1+1)*(a2+1)-1;

b = (b1+1)*(b2+1)-1;

代入原式中可得:n = (a1+1)*(b1+1)*(a2+1)*(b2+1)-1;

因为原式的朋友数都是由1,2推到出来的

所以递推到最底层,那么(a1+1)*(b1+1)*(a2+1)*(b2+1)肯定是2,3的倍数(即是1+1,2+1)

所以最后就是要解决n+1得到的数到底是不是只有2,3这些因子

 

#include <stdio.h>

int main()
{
    __int64 n;
    while(~scanf("%I64d",&n))
    {
        if(!n)
        {
            printf("NO!\n");
            continue;
        }
        n++;
        while(n%2==0)
            n/=2;
        while(n%3 == 0)
            n/=3;
        if(n==1)
            printf("YES!\n");
        else
            printf("NO!\n");
    }

    return 0;
}


 

HDU1873看病要排队这道题可以使用 C++ 结合优先队列来解决。下面给出两种使用 C++ 解决该问题的代码示例。 ### 代码示例 1 ```cpp #include<iostream> #include<queue> using namespace std; struct node { int x; // 优先级 int y; // 病人的编号 friend bool operator < (node a, node b) { if(a.x==b.x) // 如果优先级相同 return a.y>b.y; // 按顺序排 return a.x<b.x; // 按优先权排 } }; int main() { int n; while(~scanf("%d", &n)) { string s; node patient; int t = 1, a, b, x; priority_queue<node> q[4]; // 三个医生 for(int i = 1; i <= n; i++) { cin >> s; if(s == "IN") { scanf("%d%d", &a, &b); // 需要的医生和优先级 patient.x = b; // 优先级 patient.y = t++; // 编号 q[a].push(patient); // 给医生 } else { // 诊治,病人出院 scanf("%d", &x); if(q[x].empty()) puts("EMPTY"); // 当前没有病人 else { patient = q[x].top(); q[x].pop(); printf("%d\n", patient.y); // 输出病人的编号 } } } } return 0; } ``` 此代码定义了一个结构体 `node` 来表示病人,包含优先级 `x` 和病人编号 `y`。通过重载 `<` 运算符实现优先队列的排序规则,当优先级相同时按编号从小到大排序,否则按优先级从高到低排序。使用一个大小为 4 的优先队列数组 `q` 来模拟三个医生,根据输入的操作(`IN` 或 `OUT`)进行相应处理 [^1]。 ### 代码示例 2 ```cpp #include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<iostream> #include<algorithm> #include<vector> #include<stack> #include<queue> #include<set> #include<map> #include<string> using namespace std; struct node { int Dj; int id; friend bool operator<(node a, node b) { if(a.Dj == b.Dj) return a.id > b.id; return a.Dj < b.Dj; } }; int main() { node temp; char str[5]; int n = 0; while(~scanf("%d", &n)) { priority_queue<node> q[4]; temp.id = 0; while(n--) { scanf("%s", str); if(str[0] == 'I') { temp.id++; int doc, dj; scanf("%d%d", &doc, &dj); temp.Dj = dj; q[doc].push(temp); } else { int doc; scanf("%d", &doc); if(q[doc].empty()) { cout << "EMPTY" << endl; } else { cout << q[doc].top().id << endl; q[doc].pop(); } } } } return 0; } ``` 该代码同样定义了一个结构体 `node` 表示病人,包含优先级 `Dj` 和病人编号 `id`,重载 `<` 运算符实现排序规则。使用优先队列数组 `q` 模拟三个医生,根据输入的操作(以 `I` 开头表示 `IN`,其他表示 `OUT`)进行相应处理 [^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值