日常划水

1.

给你一个数n找出满足n-(n^x)-x=0的所有情况的x个数(^异或)

通过模拟前几个数我们会发现:设x为n二进制形式下1的个数,那么答案就为2^{x};

 

2.

你有一个长度为 n 序列 {a}(序列下标从1开始) ,每次可以从任意位置 i 花费 ai*i 的代价来把 ai 删除。

注意,删除后 ai 后面的数会依次向前补上(下标 -1 ) 。

求把整个序列删完的最小代价。

注:1<=n<=1e6,|ai|<=1e7保证答案在 (-2^64,2^64) 范围内

设ans = 0; 如果输入的数x为正数, ans+x; 若为负数, ans + (x*i);

输出ans;

 

3.

某一天齐木楠雄和照桥心美一起玩找数字的游戏,游戏规则是这样的,桌子上有n个的卡片,每一张卡片上都有一个独一无二的数字,心美从中选择三次(可以重复选择同一张卡片),然后得到一个数为三张卡片上数字之和,如果卡片上的数字之和恰好为k,那么心美获胜,否则齐神获胜。如果心美获胜了,齐神只能乖乖的听从心美的要求说出"哦呼了"。但是众所周知的是,心美是神的女儿,只要如果场面上存在任意一种使得和为k的方案,那么心美一定能选中这三张牌。

 

输入

对于每一个案例,我们第一行包括两个整数n,k(1<=n<=3000,1<=k<=3e5),表示有n个数字,目标和为k。第二行输入n个整数(c1 c2...cn),(1<=ci<=1e5),表示每一张卡片上的数字。

输出

如果心美能够顺利的抽出三张牌使得和恰好为k,那么输出“o hu~”,否则输出“wo yo wo yo~”。

我们先用一个数组有哪些数字出现, 再找出所有两张牌能组成的数 ,用K减去这个数看标记数组里是否存在差;

 

POJ - 2049

Nemo is a naughty boy. One day he went into the deep sea all by himself. Unfortunately, he became lost and couldn't find his way home. Therefore, he sent a signal to his father, Marlin, to ask for help.
After checking the map, Marlin found that the sea is like a labyrinth with walls and doors. All the walls are parallel to the X-axis or to the Y-axis. The thickness of the walls are assumed to be zero.
All the doors are opened on the walls and have a length of 1. Marlin cannot go through a wall unless there is a door on the wall. Because going through a door is dangerous (there may be some virulent medusas near the doors), Marlin wants to go through as few doors as he could to find Nemo.
Figure-1 shows an example of the labyrinth and the path Marlin went through to find Nemo.


We assume Marlin's initial position is at (0, 0). Given the position of Nemo and the configuration of walls and doors, please write a program to calculate the minimum number of doors Marlin has to go through in order to reach Nemo.

Input

The input consists of several test cases. Each test case is started by two non-negative integers M and N. M represents the number of walls in the labyrinth and N represents the number of doors.
Then follow M lines, each containing four integers that describe a wall in the following format:
x y d t
(x, y) indicates the lower-left point of the wall, d is the direction of the wall -- 0 means it's parallel to the X-axis and 1 means that it's parallel to the Y-axis, and t gives the length of the wall.
The coordinates of two ends of any wall will be in the range of [1,199].
Then there are N lines that give the description of the doors:
x y d
x, y, d have the same meaning as the walls. As the doors have fixed length of 1, t is omitted.
The last line of each case contains two positive float numbers:
f1 f2
(f1, f2) gives the position of Nemo. And it will not lie within any wall or door.
A test case of M = -1 and N = -1 indicates the end of input, and should not be processed.

Output

For each test case, in a separate line, please output the minimum number of doors Marlin has to go through in order to rescue his son. If he can't reach Nemo, output -1.

Sample Input

8 9
1 1 1 3
2 1 1 3
3 1 1 3
4 1 1 3
1 1 0 3
1 2 0 3
1 3 0 3
1 4 0 3
2 1 1
2 2 1
2 3 1
3 1 1
3 2 1
3 3 1
1 2 0
3 3 0
4 3 1
1.5 1.5
4 0
1 1 0 1
1 1 1 1
2 1 1 1
1 2 0 1
1.5 1.7
-1 -1

Sample Output

5
-1

经典的BFS遍历迷宫,可以用网格左下的坐标表示该网格构建三维的迷宫;用优先队列优先搜通过门少的路径;因为迷宫的大小在200以内,从终点开始搜,当前坐标大于200时,直接break;

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<map>
#include<algorithm>
#include<cmath>
using namespace std;
#define maxn 300
#define ll long long

struct t
{
    int edge[4];  // 处理网格的四面情况
}mp[maxn][maxn];

bool vis[maxn][maxn];
int mx[] = {0, 0, -1, 1};
int my[] = {1, -1, 0, 0};

struct node
{
    int x, y;
    int step;
    friend bool operator<(node a ,node b)
    {
        return a.step < b.step;
    }
    friend bool operator > (node a ,node b)
    {
        return a.step > b.step;
    }
};

int main()
{
    int m,n;
    while(~scanf("%d%d", &m, &n))
    {
        if(m+n == -2) break;
        memset(mp,0,sizeof(mp));
        for(int i = 0; i < m; i++)
        {
            int x, y, d, t;
            scanf("%d%d%d%d", &x,&y,&d,&t);
            for(int j = 0; j < t ;j++)
            {
                if(d == 0)
                {
                    mp[x+j][y].edge[1] = 1;
                    if(y > 0)
                        mp[x+j][y-1].edge[0] = 1;
                }
                else
                {
                    mp[x][y+j].edge[2] = 1;
                    if(x > 0)
                        mp[x-1][y+j].edge[3] = 1;
                }
            }

        }
        for(int i = 0; i < n; i++)
        {
            int x, y, d;
            scanf("%d%d%d", &x, &y, &d);
            if(d == 0)
            {
                mp[x][y].edge[1] = 2;
                if(y > 0) mp[x][y-1].edge[0] = 2;
            }
            else
            {
                mp[x][y].edge[2] = 2;
                if(x > 0) mp[x-1][y].edge[3] = 2;
            }
        }
        double x ,y;
        scanf("%lf%lf", &x ,&y);
        int sx, sy;
        sx =floor(x), sy = floor(y);
        if(sx < 0||sy < 0|| sx > 199|| sy > 199)
        {
            printf("0\n");
            continue;
        }
        node now;
        now.x = sx;
        now.y = sy;
        now.step = 0;
        priority_queue<node, vector<node>,greater<node> >que;
        memset(vis, false,sizeof(vis));
        vis[sx][sy] = true;
        que.push(now);
        bool flag = false;
        node ans;
        while(!que.empty())
        {

            node temp = que.top();
            // cout << temp.step << endl;
            que.pop();
            vis[temp.x][temp.y] = true;
            if(temp.x >= 200 || temp.y >= 200 || temp.x <= 0|| temp.y <= 0)
            {
                ans = temp;
                flag = true;
                break;
            }
            for(int i = 0; i < 4 ; i++)
            {
                int nx = temp.x + mx[i];
                int ny = temp.y + my[i];
                now = temp;
                if(nx >= 0&& ny >= 0 && ny < 201 && nx < 201 && !vis[nx][ny] && mp[temp.x][temp.y].edge[i]!=1)
                    //刚好可以超出迷宫的范围
                {
                    // now.step = temp.step;
                    if(mp[temp.x][temp.y].edge[i] == 2)
                        ++now.step;
                    now.x = nx;
                    now.y = ny;
                    que.push(now);
                }
            }
        }
        if(flag) printf("%d\n", ans.step);
        else cout << -1 << endl;
    }
}

/*
4 1
3 2 1 1
1 3 0 2
1 1 0 2
1 1 1 2
2 1 1
1.5 1.5
*/

随带学了一波优先队列:

基本操作:

q.empty()     如果队列为空,则返回true,否则返回false 
q.size()      返回队列中元素的个数 
q.pop()       删除队首元素,但不返回其值 
q.top()       返回具有最高优先级的元素值,但不删除该元素 
q.push(item)  在基于优先级的适当位置插入新元素

默认优先级:

从大到小;

自定义优先级:

#include <queue> 
using namespace std; 
struct node 
{ 
    int priority; 
    int value; 
    friend bool operator < (const node &a, const node &b)
     { return a.priority < b.priority; }
};

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值