首页 > 试题广场 >

像素设定

[编程题]像素设定
  • 热度指数:7936 时间限制:C/C++ 3秒,其他语言6秒 空间限制:C/C++ 32M,其他语言64M
  • 算法知识视频讲解

有一个单色屏幕储存在一维数组中,给定表示屏幕的数组screen(数组中元素二进制表达的每一位分别对应连续的8个像素,二进制位数的从低到高对应像素的从左到右),用函数实现将第x到第y个像素涂上颜色(像素标号从零开始),返回涂色后的新的屏幕数组。请尝试尽量使用最快的办法并保证输入数据合法性。

测试样例:
[0,0,0,0,0,0],0,47
返回:[255,255,255,255,255,255]
    /*
    基本上大意就是从第x 到第y位 ,其中的像素全部变为0,如此两种情况 :
        0-->1, 1-->1 ,所以这时候就很清楚的用 位操作中的 ' | '
    */
    vector<int> renderPixel(vector<int> screen, int x, int y) {
        for(int i = x ; i <= y ; i ++)
        {
            int k = i % 8 ;
            int t = i / 8 ;
            screen[t] = screen[t] | (1<< k);
        }

        return screen ;
    }
发表于 2015-10-30 16:37:20 回复(5)
又是一道题目意思很难理解的。。。

举个例子  screen=[0, 1], x=3, y=9
首先,screen每个元素表示8个像素(也就是它的二进制表示),把screen每个元素转为二进制(低位在左):
00000000  10000000
然后将第x至第y个(从左至右)二进制位变为1:
00011111   11000000
然后转为十进制,由于低位在左,先逆序:
00011111   --->  11111000  --->  248
11000000  --->  00000011  ---> 3
所以结果为 [248, 3]

# -*- coding:utf-8 -*-
class Render:
    def renderPixel(self, screen, x, y):
        px = ('0' * x + '1' * (y - x + 1)).ljust(8 * len(screen), '0')
        return [(int(px[i:i+8][::-1], 2) | screen[i//8]) for i in range(0, len(px), 8)]

发表于 2018-12-27 10:51:14 回复(0)
有一个点要注意:数组 screen (数组中的每个元素代表连续的8个像素,且从左至右的像素分别对应元素的二进制的从低到高位)

# -*- coding:utf-8 -*-
class Render:
    def renderPixel(self, screen, x, y):
        for i in range(x, y + 1):
            # 找出处于元素的哪一位 (从低到高)
            k = i % 8
            # 找出哪一个元素
            t = i / 8
            screen[t] = screen[t] | (1 << k)
        return screen

发表于 2016-08-04 09:10:53 回复(0)
    public int[] renderPixel(int[] screen, int x, int y) {
		int start = x / 8, end = y / 8;
		int f1 = x % 8, f2 = y % 8 + 1;//f1表示起始位0的个数,f2表示终止位1的个数
		if (end - start > 0) {
			for (int i = start + 1; i < end; i++) {
				screen[i] = 0xff;
			}
			screen[start] |= 0xff & ~((1<<f1)-1);
			screen[end]	|= (1<<f2) - 1;
		} else {
			screen[start] |= 0xff & ~((1<<f1)-1) & ((1<<f2)-1);
		}
		
		return screen;
	}

编辑于 2016-04-10 11:57:14 回复(0)
class Render {
public:
    vector<int> renderPixel(vector<int> screen, int x, int y) {
        // write code here
        for(int i = x / 8 + 1; i < y / 8 ; i ++ ) screen[i] = 255;
        for(int i = x % 8; i < 8; i++)  screen[x / 8] = screen[x / 8] | (1 << i);
        for(int i = y % 8; y / 8 != x / 8 && i >= 0; i--) screen[y / 8] = screen[y / 8] | (1 << i);
        return screen;
    }
};

发表于 2019-06-11 00:31:49 回复(0)
思路:首先解释一下题目的意思,我刚开始没搞懂,怀疑自己是不是中国人了hh,题目给的全是0的
二维数组,x和y代表需要让填充颜色的像素点,在x-y这个范围的像素点变为1(即数组元素的对应二进制位
变为1),这个就可以用位运算符,|来进行操作了,对吧,t是行数,k是在行中的位置。
class Render {
public:
    vector<int> renderPixel(vector<int> screen, int x, int y) {
 for(int i = x ; i <= y ; i ++)
        {
            int k = i % 8 ;
            int t = i / 8 ;
            screen[t] = screen[t] | (1<< k);
        }
        return screen ;
    }
};

发表于 2017-09-08 09:29:20 回复(1)
//题目要求高效,中间连续8位的可以整个设置,而不是一个bit一个bit的设置,提高了效率
class Render {
public:
    vector<int> renderPixel(vector<int> screen, int x, int y) {
        int size = screen.size();
        vector<int> ans;
        if(x<0 || y/8 > size || x>y)//异常检验
            return screen;
            
        int startOffset = x%8;//初始offset
        int firstFullByte = x/8 + 1;//第一个完整位置
        int endOffset = y%8;//末端offset
        int lastFullByte = y/8 - 1;//最后一个完整位置
        
        for(int i = firstFullByte; i <= lastFullByte; ++i){
            screen[i] = 255;//中间部分是完整8位的一次性设置
        }
        
        int startMask = (255<<startOffset) & 255;//头掩码
        int endMask = 255>>(7-endOffset);//尾掩码,注意是从低位到高位设置
        //最后是第一个节点和最后一个节点的设置
        if( x/8 == y/8){//处于同一个字节内的特殊情况处理
            int mask = startMask & endMask;
            screen[x/8] |= mask;
        }
        else{
            screen[x/8] |= startMask;
            screen[y/8] |= endMask;
        }
        return screen;
    }
};

发表于 2015-10-05 23:51:04 回复(0)
Ron头像 Ron
/*这题很恶心,screen中存放的数字都是以8位二进制数表示
x为开始涂色的起点,y为终点
先定好下标,startIndex=x/8和endIndex = y/8找到screen中位置
然后看该数的那几位需要涂色。
1. endIndex - startIndex == 0且x <= y,将startIndex对应
下标下的数的第x到第y位涂色
2. endIndex - startIndex > 0且x <= y,将startIndex对应
下标的数从x到最高位进行涂色;
将endIndex对应下标的数从最低位到y进行涂色,startIndex
到endIndex之间的数全部为涂色,都为255
*/
	public int[] renderPixel(int[] screen, int x, int y) {
		// write code here
		int[] res = new int[screen.length];
		int len = screen.length;
		int startIndex = x/8;
		int endIndex = y/8;
		for(int i = 0; i < screen.length; i++){
			if(i < startIndex){
				res[i] = screen[i];
			}else if( i >= startIndex && i <= endIndex){
				if(endIndex - startIndex > 0){//覆盖多于一个像素
					if(i == startIndex){
						res[i] = screen[i] | getNumStart(x%8);
					}else if(i == endIndex){
						res[i] = screen[i] | getNumEnd(y%8);
					}else{
						res[i] = 255;
					}
				}else{//覆盖少于一个像素
					res[i] = screen[i] | (getNumStart(x%8)&(getNumEnd(y%8)));
				}
			}else if(i > endIndex && i < len){
				res[i] = screen[i];
			}
		}
		return res;
	}
	public int reverseBit(int num) {
		// TODO Auto-generated method stub
		int round = 7;
		int res = 0;
		while(round >= 0){
			res |= (((num >> round) & 1)==0) ? 0: (1 << (7-round));
			round--;
		}
		return res;
	}
	public int getNumStart(int bit) {
		// TODO Auto-generated method stub
		return reverseBit((int) (Math.pow(2, 8-bit)-1));
	}
	public int getNumEnd(int bit){
		return (int) (Math.pow(2, bit+1)-1);
	}

编辑于 2015-10-23 16:52:23 回复(1)
把x和y所在数组的位置之间的数组元素都赋值为255,而x和y所在位置的元素要仔细处理。
还有题目中“且从左至右的像素分别对应元素的二进制的从低到高位 ”应该这样理解, 例如[0,0,0],4,19的二进制结果应该为[11110000,11111111,00001111]。
代码如下:
public class Render {
    public int[] renderPixel(int[] screen, int x, int y) {
        int start = x / 8, startPos = x % 8, end = y / 8, endPos = y % 8;
        screen[start] = (0xFF << startPos) & 0xFF | screen[start];
        for (int i = start + 1; i < end; ++i) {
            screen[i] = 255;
        }
        screen[end] = (~(0xFF << (endPos + 1))) & (start == end ? screen[start] : 0xFF) | screen[end];
        return screen;
    }
}

发表于 2017-06-19 14:57:36 回复(0)
//还是这种方法简单明了,Java版本
import java.util.*; public class Render {
    public int[] renderPixel(int[] screen, int x, int y) {
        for(int i = x; i <= y; i++){
            int n = i / 8;
            int nBit = i % 8;
            screen[n] |= (1 << nBit);
        }
        return screen;
    }
}
发表于 2017-05-18 16:47:03 回复(0)
public int[] renderPixel(int[] screen, int x, int y) {
    int index = 0;
    int position = 0;
    for (int i = x; i <= y; i++) {
        index = i/8;//计算索引
        position =i % 8;//计算位置
        screen[index]|=(1<<position);//或操作,因为该位置如果是0则变成1,如果是1则仍为1
    }
    return screen;
}
发表于 2017-03-02 15:37:30 回复(0)
public int[] renderPixel(int[] screen, int x, int y) {
        // write code here
        for (int i = x; i <= y; i++) {
            int num = i / 8;
            int bit = i % 8;
            screen[num] |= (1 << bit);
        }
        return screen;
    }
编辑于 2016-12-17 12:32:29 回复(1)
import java.util.*;

public class Render {
  public int[] renderPixel(int[] screen, int x, int y) {
       int firstbyte=x/8;
       int startoffest=x%8;
       int lastbyte=y/8;
       int endoffest=y%8;
       int startmark=255^((1<<startoffest)-1);
       int endmark=((1<<(endoffest+1))-1);
       //如果覆盖的是一个字节
       if(firstbyte==lastbyte){
           screen[firstbyte]|=(startmark&endmark);
           return screen;
       }
       //否则就将多个字节中间部分都覆盖
       for(int i=firstbyte+1;i<lastbyte;i++)
           screen[i]=255;
       //再用掩码对两端处理
       screen[firstbyte]|=startmark;
       screen[lastbyte]|=endmark;
       return screen;
   }
}
发表于 2016-02-03 00:14:27 回复(0)
L0L头像 L0L
 vector<int> renderPixel(vector<int> screen, int x, int y) {
        int start = x/8;
        int end = y/8;
        int i;
        if(start<end){
            for(i=x%8;i<8;i++)
                screen[start] |= (0x1<<i);
            for(i=start+1;i<end;i++)
                screen[i] |= 0xff;
            for(i=0;i<=y%8;i++)
                screen[end] |= (0x1<<i);
        }else{
            for(i=x%8;i<=y%8;i++)
                screen[start] |= (0x1<<i);
        }
        return screen;
    }

发表于 2015-10-14 15:11:09 回复(0)
是我语文水平差?我几次没读懂题目了-_-||
发表于 2017-07-12 09:34:46 回复(0)
高低位相反真的绕
这个题目可能实际中真能用到,写一个非一次性的代码
class Render {
public:
    vector<int> renderPixel(vector<int> screen, int x, int y) {
        // 低8位有效
        constexpr unsigned int BitWidth = 8U;
        constexpr unsigned int BitMask = ~(UINT_MAX << BitWidth);

        const size_t size = screen.size();

        // 题目说了检查输入合法性,没说不合法怎么办
        // 于是默认什么也不做
        if (
            size < 1U
            || x < 0 || x > size * BitWidth
            || y < 0 || y > size * BitWidth
        ) {
            return screen;
        }

        // 操作原生数组,也许比通过vector快一些?
        // 不知道,但是原生数组的速度绝不会慢
        int* const data = screen.data();
        const unsigned int l = x / BitWidth;
        const unsigned int r = y / BitWidth;

        // 左右边界之后单独处理,中间部分先直接填满
        for (unsigned int i = l + 1; i < r; ++i) {
            data[i] = BitMask;
        }

        // 最后额外的&BitMask,是要把更高位的数值抹掉,
        // 因为int通常不止8位,但这题让int屈尊表示只有8位的数
        const int mask_left = static_cast<int>(
             (BitMask << ((x % BitWidth))) & BitMask
         );
        const int mask_right = static_cast<int>(
             (BitMask >> (BitWidth - (y % BitWidth) - 1)) & BitMask
         );

        if (l == r) {
            data[l] |= mask_left & mask_right;
        }
        else {
            data[l] |= mask_left;
            data[r] |= mask_right;
        }
        return screen;
    }

};


发表于 2022-02-08 14:45:15 回复(0)
int[] binary = {1,2,4,8,16,32,64,128};

        int i = 0;
        while (i< screen.length *8){

            if(i >= x && i <=y){
                int k = i / 8;

                int bit = i % 8;
                int tmp = screen[k];
                tmp = tmp >> bit;
                if(tmp %2 == 0){
                    screen[k] += binary[bit];
                }
            }

            i++;
        }

        return screen;
    }

发表于 2020-07-08 16:47:42 回复(0)
class Render {
public:
    vector<int> renderPixel(vector<int> screen, int x, int y) {
        int length=screen.size();
        vector<int>res;
        for(int i=0;i<length;++i)
        {
            int num=0;
            for(int j=0;j<8;++j)
            {
                if(i*8+j>=x&&i*8+j<=y)
                {
                    num+=pow(2,j);
                }
            }
            res.push_back(screen[i]|num);
        }
        return res;
    }
};

//两层循环,第一层循环遍历screen中的每一个数,第二层循环遍历8位像素值,在第二层循环中i*8+j判的像素断当前的j是位于从最左开始第几位,并判断j位是否介于x和y之间,即是否被设置成1,代表每8位为一组,每组中涂色所代表的的数字,把num和screen[i]做位或运算求出来的结果即为涂改后的数字

发表于 2020-07-06 11:27:28 回复(0)
//[0,0,0,0,0,0],1,45
    vector<int> renderPixel(vector<int> screen, int x, int y) {
        const int max_val = 255;
        // write code here
        if(y<x) return screen;
		
        int n = screen.size();
		
        int x_index = x/8,x_bit = x%8;//x开始涂色的元素位置,开始涂色的位号
		if(x_index>=n) return screen;
		int y_index = y/8,y_bit = y%8;//终止涂色的元素位置 终止的位号
		//从screen中x_index的x_bit位开始涂色,直到y_index的y_bit
		//为了加速涂色,将满8bit的一次处理,只有x_index或y_index的位有可能要单独处理,(x_index,y_index)一起处理
		for(auto i=x_index+1;i<n and i<y_index;i++){
            screen[i]=255;
        }
		
		screen[x_index] |= max_val^((1<<x_bit)-1);
		if(y_index>=n&nbs***bsp;x_index==y_index) return screen;
		if(y_bit==7) screen[y_index] = 255;
		else screen[y_index] |= (1<<(y_bit+1))-1;
        
        return screen;
    }

发表于 2020-02-10 08:49:13 回复(0)
// 且从左至右的像素分别对应元素的二进制的从低到高位
// 最开始被这个误导了。

class Render {
public:
    vector<int> renderPixel(vector<int> screen, int x, int y) {
        // write code here
        int numberIndex;
        int siteIndex;
        for (int i  = x; i <= y; i++) {
            numberIndex = i / 8;
            siteIndex = i % 8;
            screen[numberIndex]  = screen[numberIndex] | (1 << siteIndex);
        }
        return screen;
    }
};


发表于 2019-07-02 22:52:18 回复(0)