outdated: 37.Cel-Shading

2023-11-22 17:10
文章标签 37 shading outdated cel

本文主要是介绍outdated: 37.Cel-Shading,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

卡通人物的贴图及阴影实现。

在抗锯齿方面,OpenGL中只需glEnable(GL_LINE_SMOOTH)。

对于一个向量的旋转,直接乘以旋转矩阵可以得出。下面为代码,

void RotateVector(MATRIX &M, VECTOR &V, VECTOR &D)            // Rotate a vector
{D.X = M.Data[0] * V.X + M.Data[4] * V.Y + M.Data[8] * V.Z;    // Rotate round the x axisD.Y = M.Data[1] * V.X + M.Data[5] * V.Y + M.Data[9] * V.Z;    // Rotate round the y axisD.Z = M.Data[2] * V.X + M.Data[6] * V.Y + M.Data[10] * V.Z;   // Rotate round the z axis
}

灯光设置为Z轴正方向(0,0,1),然后计算其法向量normal,接着再和旋转后的向量来个点积得到shade值。若小于零,就设置为零。这个shade值可以作为一维贴图坐标。

对于边框线条,首先得开启glEnable(GL_BLEND),然后设置blend mode即glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA),接着glPolygonMode(GL_BACK, GL_LINE)画反面多边形,最后是深度缓存glDepthFunc(GL_LEQUAL)。

下面为代码,

#ifndef GL_FRAMEWORK_INCLUDED
#define GL_FRAMEWORK_INCLUDED#include <windows.h>typedef struct {                                   // Structure for keyboard stuffBOOL keyDown[256];
} Keys;typedef struct {                                   // Contains information vital to applications HMODULE hInstance;                             // Application Instanceconst char* className;
} Application;typedef struct {                                   // Window creation infoApplication* application;char* title;int width;int height;int bitsPerPixel;BOOL isFullScreen;
} GL_WindowInit;typedef struct {                                   // Contains information vital to a windowKeys* keys;HWND hWnd;                                     // Windows handleHDC hDC;                                       // Device contextHGLRC hRC;                                     // Rendering context
    GL_WindowInit init;BOOL isVisible;                                // Window visiable?DWORD lastTickCount;                           // Tick counter
} GL_Window;void TerminateApplication(GL_Window* window);      // Terminate the applicationvoid ToggleFullscreen(GL_Window* window);          // Toggle fullscreen / Windowed mode

BOOL Initialize(GL_Window* window, Keys* keys);void Deinitialize(void);void Update(DWORD milliseconds);void Draw(void);#endif
Previous.h
#include <Windows.h>
#include <GL\glew.h>
#include <GL\glut.h>
#include "Previous.h"#define WM_TOGGLEFULLSCREEN (WM_USER+1)                   // Application define message for toggling 
// between fulscreen / windowed mode
static BOOL g_isProgramLooping;                           // Window creation loop, for fullscreen / windowed mode
static BOOL g_createFullScreen;                           // If true, then create windowvoid TerminateApplication(GL_Window* window)              // Terminate the application
{PostMessage(window->hWnd, WM_QUIT, 0, 0);             // Send a WM_QUIT messageg_isProgramLooping = FALSE;                           // Stop looping of the program
}void ToggleFullscreen(GL_Window* window)                  // Toggle fullscreen /windowed mode
{PostMessage(window->hWnd, WM_TOGGLEFULLSCREEN, 0, 0); // Send a WM_TOGGLEFULLSCREEN message
}void ReshapeGL(int width, int height)                     // Reshape the window  when it's moved or resized
{glViewport(0, 0, (GLsizei)(width), (GLsizei)(height)); // Reset the current viewport
    glMatrixMode(GL_PROJECTION);glLoadIdentity();// Calcutate the aspect ratio of the windowgluPerspective(45.0f, (GLfloat)(width) / (GLfloat)(height), 1.0, 100.0f);glMatrixMode(GL_MODELVIEW);glLoadIdentity();
}BOOL ChangeScreenResolution(int width, int height, int bitsPerPixel)     // Change the screen resolution
{DEVMODE dmScreenSettings;                              // Device modeZeroMemory(&dmScreenSettings, sizeof(DEVMODE));        // Make sure memory is cleareddmScreenSettings.dmSize = sizeof(DEVMODE);             // Size of the devmode structuredmScreenSettings.dmPelsWidth = width;dmScreenSettings.dmPelsHeight = height;dmScreenSettings.dmBitsPerPel = bitsPerPixel;dmScreenSettings.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;if (ChangeDisplaySettings(&dmScreenSettings, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL) {return FALSE;                                      // Display change failed
    }return TRUE;
}BOOL CreateWindowGL(GL_Window* window)
{DWORD windowStyle = WS_OVERLAPPEDWINDOW;                // Define window styleDWORD windowExtendedStyle = WS_EX_APPWINDOW;            // Define the window's extended style
PIXELFORMATDESCRIPTOR pdf = {sizeof(PIXELFORMATDESCRIPTOR),                      // Size of this pixel format descriptor1,                                                  // Version NumberPFD_DRAW_TO_WINDOW |                                // Format must support windowPFD_SUPPORT_OPENGL |                                // Format must support openGLPFD_DOUBLEBUFFER,                                   // Must support double bufferingPFD_TYPE_RGBA,                                      // Request an RGBA formatwindow->init.bitsPerPixel,                          // Select color depth0, 0, 0, 0, 0, 0,                                   // Color bits ignored0,                                                  // No alpha buffer0,                                                  // Shift bit ignored0,                                                  // No accumulation buffer0, 0, 0, 0,                                         // Accumulation bits ignored16,                                                 // 16bits Z-buffer (depth buffer)0,                                                  // No stencil buffer0,                                                  // No auxiliary bufferPFD_MAIN_PLANE,                                     // Main drawing layer0,                                                  // Reserved0, 0, 0                                             // Layer masks ignored
    };RECT windowRect = { 0, 0, window->init.width, window->init.height };   // Window coordiantes
GLuint PixelFormat;if (window->init.isFullScreen == TRUE) {if (ChangeScreenResolution(window->init.width, window->init.height, window->init.bitsPerPixel) == FALSE){// Fullscreen mode failed, run in windowed mode insteadMessageBox(HWND_DESKTOP, "Mode Switch Failed.\nRuning In Windowed Mode.","Error", MB_OK | MB_ICONEXCLAMATION);window->init.isFullScreen = FALSE;}else {ShowCursor(FALSE);windowStyle = WS_POPUP;                         // Popup windowwindowExtendedStyle |= WS_EX_TOPMOST;}}else {// Adjust window, account for window bordersAdjustWindowRectEx(&windowRect, windowStyle, 0, windowExtendedStyle);}// Create Opengl windowwindow->hWnd = CreateWindowEx(windowExtendedStyle,      // Extended stylewindow->init.application->className,                // Class namewindow->init.title,                                 // Window titlewindowStyle,                                        // Window style0, 0,                                               // Window X,Y positionwindowRect.right - windowRect.left,                 // Window widthwindowRect.bottom - windowRect.top,                 // Window heightHWND_DESKTOP,                                       // Desktop is window's parent0,                                                  // No menuwindow->init.application->hInstance,                // Pass the window instance
        window);if (window->hWnd == 0) {                                // Was window creation a success?return FALSE;}window->hDC = GetDC(window->hWnd);if (window->hDC == 0) {DestroyWindow(window->hWnd);window->hWnd = 0;return FALSE;}PixelFormat = ChoosePixelFormat(window->hDC, &pdf);     // Find a compatible pixel formatif (PixelFormat == 0) {ReleaseDC(window->hWnd, window->hDC);               // Release device contextwindow->hDC = 0;DestroyWindow(window->hWnd);window->hWnd = 0;return FALSE;}if (SetPixelFormat(window->hDC, PixelFormat, &pdf) == FALSE) {   // Try to set the pixel formatReleaseDC(window->hWnd, window->hDC);window->hDC = 0;DestroyWindow(window->hWnd);window->hWnd = 0;return FALSE;}window->hRC = wglCreateContext(window->hDC);            // Try to get a rendering contextif (window->hRC == 0) {ReleaseDC(window->hWnd, window->hDC);window->hDC = 0;DestroyWindow(window->hWnd);window->hWnd = 0;return FALSE;}// Make the rendering context our current rendering contextif (wglMakeCurrent(window->hDC, window->hRC) == FALSE) {wglDeleteContext(window->hRC);                      //  Delete the rendering contextwindow->hRC = 0;ReleaseDC(window->hWnd, window->hDC);window->hDC = 0;DestroyWindow(window->hWnd);window->hWnd = 0;return FALSE;}ShowWindow(window->hWnd, SW_NORMAL);                    // Make the window visiablewindow->isVisible = TRUE;ReshapeGL(window->init.width, window->init.height);     // Reshape our GL windowZeroMemory(window->keys, sizeof(Keys));                 // Clear all keyswindow->lastTickCount = GetTickCount();return TRUE;
}BOOL DestoryWindowGL(GL_Window* window)
{if (window->hWnd != 0) {if (window->hDC != 0) {wglMakeCurrent(window->hDC, 0);                 // Setting current active rendering context to zeroif (window->hRC != 0) {wglDeleteContext(window->hRC);window->hRC = 0;}ReleaseDC(window->hWnd, window->hDC);window->hDC = 0;}DestroyWindow(window->hWnd);window->hWnd = 0;}if (window->init.isFullScreen) {ChangeDisplaySettings(NULL, 0);                     // Switch back to desktop resolution
        ShowCursor(TRUE);}return TRUE;
}// Process window message callback
LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{// Get the window contextGL_Window* window = (GL_Window*)(GetWindowLong(hWnd, GWL_USERDATA));switch (uMsg) {                                         // Evaluate window messagecase WM_SYSCOMMAND:                                     // Intercept system commands
    {switch (wParam) {                                   // Check system callscase SC_SCREENSAVE:                                 // Screensaver trying to start?case SC_MONITORPOWER:                               // Mointer trying to enter powersave?return 0;                                           // Prevent form happening
        }break;}return 0;case WM_CREATE:{CREATESTRUCT* creation = (CREATESTRUCT*)(lParam);   // Store window structure pointerwindow = (GL_Window*)(creation->lpCreateParams);SetWindowLong(hWnd, GWL_USERDATA, (LONG)(window));}return 0;case WM_CLOSE:TerminateApplication(window);return 0;case WM_SIZE:switch (wParam) {case SIZE_MINIMIZED:                                 // Was window minimized?window->isVisible = FALSE;return 0;case SIZE_MAXIMIZED:window->isVisible = TRUE;ReshapeGL(LOWORD(lParam), HIWORD(lParam));return 0;case SIZE_RESTORED:window->isVisible = TRUE;ReshapeGL(LOWORD(lParam), HIWORD(lParam));return 0;}break;case WM_KEYDOWN:if ((wParam >= 0) && (wParam <= 255)) {window->keys->keyDown[wParam] = TRUE;            // Set the selected key(wParam) to truereturn 0;}break;case WM_KEYUP:if ((wParam >= 0) && (wParam <= 255)) {window->keys->keyDown[wParam] = FALSE;return 0;}break;case WM_TOGGLEFULLSCREEN:g_createFullScreen = (g_createFullScreen == TRUE) ? FALSE : TRUE;PostMessage(hWnd, WM_QUIT, 0, 0);break;}return DefWindowProc(hWnd, uMsg, wParam, lParam);        // Pass unhandle message to DefWindowProc
}BOOL RegisterWindowClass(Application* application)
{WNDCLASSEX windowClass;ZeroMemory(&windowClass, sizeof(WNDCLASSEX));            // Make sure memory is clearedwindowClass.cbSize = sizeof(WNDCLASSEX);                 // Size of the windowClass structurewindowClass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;  // Redraws the window for any movement / resizingwindowClass.lpfnWndProc = (WNDPROC)(WindowProc);         // WindowProc handles messagewindowClass.hInstance = application->hInstance;          // Set the instancewindowClass.hbrBackground = (HBRUSH)(COLOR_APPWORKSPACE);// Class background brush colorwindowClass.hCursor = LoadCursor(NULL, IDC_ARROW);       // Load the arrow pointerwindowClass.lpszClassName = application->className;      // Sets the application classNameif (RegisterClassEx(&windowClass) == 0) {MessageBox(HWND_DESKTOP, "RegisterClassEx Failed!", "Error", MB_OK | MB_ICONEXCLAMATION);return FALSE;}return TRUE;
}int WINAPI WinMain(HINSTANCE hIstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{Application application;GL_Window window;Keys keys;BOOL isMessagePumpActive;MSG msg;DWORD tickCount;application.className = "OpenGL";application.hInstance = hIstance;ZeroMemory(&window, sizeof(GL_Window));window.keys = &keys;                                     // Window key structurewindow.init.application = &application;                  // Window applicationwindow.init.title = "Cel-Shading";                       // Window titlewindow.init.width = 640;                                 // Window widthwindow.init.height = 480;                                // Window heightwindow.init.bitsPerPixel = 16;                           // Bits per pixelwindow.init.isFullScreen = TRUE;                         // Fullscreen? (set to TRUE)
ZeroMemory(&keys, sizeof(Keys));if (MessageBox(HWND_DESKTOP, "Would You Like To Run In Fullscreen Mode?", "Start FullScreen?",MB_YESNO | MB_ICONQUESTION) == IDNO){window.init.isFullScreen = FALSE;}if (RegisterWindowClass(&application) == FALSE){MessageBox(HWND_DESKTOP, "Error Registering Window Class!", "Error", MB_OK | MB_ICONEXCLAMATION);return -1;}g_isProgramLooping = TRUE;g_createFullScreen = window.init.isFullScreen;while (g_isProgramLooping) {                             // Loop until WM_QUIT is receivedwindow.init.isFullScreen = g_createFullScreen;       // Set init param of window creation to fullscreen?if (CreateWindowGL(&window) == TRUE) {               // Was window creation successful?// At this point we should have a window that is setup to render OpenGLif (Initialize(&window, &keys) == FALSE) {TerminateApplication(&window);               // Close window, this will handle the shutdown
            }else {isMessagePumpActive = TRUE;while (isMessagePumpActive == TRUE) {// Success creating window. Check for window messagesif (PeekMessage(&msg, window.hWnd, 0, 0, PM_REMOVE) != 0) {if (msg.message != WM_QUIT) {DispatchMessage(&msg);}else {isMessagePumpActive = FALSE;     // Terminate the message pump
                        }}else {if (window.isVisible == FALSE) {WaitMessage();                   // Application is minimized wait for a message
                        }else {// Process application looptickCount = GetTickCount();      // Get the tick countUpdate(tickCount - window.lastTickCount); // Update the counterwindow.lastTickCount = tickCount;// Set last count to current countDraw();                          // Draw screen
                            SwapBuffers(window.hDC);}}}}// Application is finished
            Deinitialize();DestoryWindowGL(&window);}else {MessageBox(HWND_DESKTOP, "Error Creating OpenGL Window", "Error", MB_OK | MB_ICONEXCLAMATION);g_isProgramLooping = FALSE;}}UnregisterClass(application.className, application.hInstance);    // UnRegister window classreturn 0;
}
Previous.cpp
#include <Windows.h>
#include <GL/glew.h>
#include <GL/glut.h>
#include <GL/GLUAX.H>
#include <math.h>
#include <stdio.h>
#include "Previous.h"#pragma comment(lib, "legacy_stdio_definitions.lib")#ifndef CDS_FULLSCREEN
#define CDS_FULLSCREEN 4
#endifGL_Window* g_window;
Keys* g_keys;typedef struct tagMATRIX {float Data[16];                  // Matrix format
} MATRIX;typedef struct tagVECTOR {float X, Y, Z;
} VECTOR;typedef struct tagVERTEX {VECTOR Nor;                      // NormalVECTOR Pos;                      // Position
} VERTEX;typedef struct tagPOLYGON {          // PolygonVERTEX Verts[3];
} POLYGON;bool outlineDraw = true;             // Flag to draw the outline
bool outlineSmooth = false;          // Flag to Anti-Alias the lines
float outlineColor[3] = { 0.0f, 0.0f, 0.0f };     // Color of the line
float outlineWidth = 3.0f;           // Width of the lines

VECTOR lightAngle;                   // The direction of the light
bool lightRotate = false;            // Flag to see if rotate the lightfloat modelAngle = 0.0f;             // Y-axis angle of the model
bool modelRotate = false;            // Flag to rotate the model

POLYGON* polyData = NULL;            // Polygon data
int polyNum = 0;                     // Number of polygon

GLuint shaderTexture[1];             // Storage for one texture

BOOL ReadMesh()
{FILE* In = fopen("Data/model.txt", "rb");if (!In) {return FALSE;}fread(&polyNum, sizeof(int), 1, In);    // Read the header (number of polygon)polyData = (POLYGON*)malloc(sizeof(POLYGON) * polyNum);fread(&polyData[0], sizeof(POLYGON) * polyNum, 1, In);fclose(In);return TRUE;
}inline float DotProduct(VECTOR &V1, VECTOR &V2)
{return V1.X * V2.X + V1.Y * V2.Y + V1.Z * V2.Z;
}inline float Magnitude(VECTOR &V)                    // The length of the vector
{return sqrt(V.X * V.X + V.Y * V.Y + V.Z * V.Z);
}void Normalize(VECTOR &V)                            // Create a vector with a unit length of 1
{float M = Magnitude(V);if (M != 0.0f) {V.X /= M;V.Y /= M;V.Z /= M;}
}void RotateVector(MATRIX &M, VECTOR &V, VECTOR &D)            // Rotate a vector
{D.X = M.Data[0] * V.X + M.Data[4] * V.Y + M.Data[8] * V.Z;    // Rotate round the x axisD.Y = M.Data[1] * V.X + M.Data[5] * V.Y + M.Data[9] * V.Z;    // Rotate round the y axisD.Z = M.Data[2] * V.X + M.Data[6] * V.Y + M.Data[10] * V.Z;   // Rotate round the z axis
}BOOL Initialize(GL_Window* window, Keys* keys)
{char Line[255];float shaderData[32][3];FILE *In = NULL;g_window = window;g_keys = keys;glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);     // Realy nice perspective calculationsglClearColor(0.1f, 0.1f, 0.1f, 0.0f);glClearDepth(1.0f);    glEnable(GL_DEPTH_TEST);glDepthFunc(GL_LESS);glShadeModel(GL_SMOOTH);glDisable(GL_LINE_SMOOTH);glEnable(GL_CULL_FACE);glDisable(GL_LIGHTING);In = fopen("Data/shader.txt", "r");if (In) {for (int i = 0; i < 32; i++) {if (feof(In)) break;fgets(Line, 255, In);shaderData[i][0] = shaderData[i][1] = shaderData[i][2] = float(atof(Line));}fclose(In);}else {return FALSE;}glGenTextures(1, &shaderTexture[0]);glBindTexture(GL_TEXTURE_1D, shaderTexture[0]);glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);glTexImage1D(GL_TEXTURE_1D, 0, GL_RGB, 32, 0, GL_RGB, GL_FLOAT, shaderData);lightAngle.X = 0.0f;lightAngle.Y = 0.0f;lightAngle.Z = 1.0f;Normalize(lightAngle);return ReadMesh();
}void Deinitialize(void)
{glDeleteTextures(1, &shaderTexture[0]);free(polyData);
}void Update(DWORD milliseconds)
{if (g_keys->keyDown[' '] == TRUE) {modelRotate = !modelRotate;                  // Toggle model rotationg_keys->keyDown[' '] = FALSE;}if (g_keys->keyDown['1'] == TRUE) {outlineDraw = !outlineDraw;                  // Tpggle outline drawingg_keys->keyDown['1'] = FALSE;}if (g_keys->keyDown['2'] == TRUE) {outlineSmooth = !outlineSmooth;              // Toggle Anti-Aliasingg_keys->keyDown['2'] = FALSE;}if (g_keys->keyDown[VK_UP] == TRUE) {outlineWidth++;                              // Line widthg_keys->keyDown[VK_UP] = FALSE;}if (g_keys->keyDown[VK_DOWN] == TRUE) {outlineWidth--;                              // Line widthg_keys->keyDown[VK_DOWN] = FALSE;}if (modelRotate) {modelAngle += (float)(milliseconds) / 10.0f;}
}void Draw()
{float TmpShade;                // Temporary shader value
    MATRIX TmpMatrix;VECTOR TmpVector, TmpNormal;glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);glLoadIdentity();if (outlineSmooth) {           // Check
        glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);glEnable(GL_LINE_SMOOTH);                // Enable Anti-Aliasing
    }else {glDisable(GL_LINE_SMOOTH);}glTranslatef(0.0f, 0.0f, -2.0f);glRotatef(modelAngle, 0.0f, 1.0f, 0.0f);glGetFloatv(GL_MODELVIEW_MATRIX, TmpMatrix.Data);      // Get the generatef matrix// Cel-shading code
    glEnable(GL_TEXTURE_1D);glBindTexture(GL_TEXTURE_1D, shaderTexture[0]);glColor3f(0.8f, 0.2f, 0.2f);glBegin(GL_TRIANGLES);for (int i = 0; i < polyNum; ++i) {for (int j = 0; j < 3; ++j) {TmpNormal.X = polyData[i].Verts[j].Nor.X;TmpNormal.Y = polyData[i].Verts[j].Nor.Y;TmpNormal.Z = polyData[i].Verts[j].Nor.Z;RotateVector(TmpMatrix, TmpNormal, TmpVector);     // Rotate
            Normalize(TmpVector);TmpShade = DotProduct(TmpVector, lightAngle);if (TmpShade < 0.0f) {TmpShade = 0.0f;}glTexCoord1f(TmpShade);          // Set the texture coordinate as the shade valueglVertex3fv(&polyData[i].Verts[j].Pos.X);}}glEnd();glDisable(GL_TEXTURE_1D);if (outlineDraw) {             // Check
        glEnable(GL_BLEND);glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);   // Blend mode
glPolygonMode(GL_BACK, GL_LINE);           // Draw backfacing polygon as wireframes
        glLineWidth(outlineWidth);glCullFace(GL_FRONT);                      // Don't draw any front-face polygon
        glDepthFunc(GL_LEQUAL);glColor3fv(&outlineColor[0]);              // Set the outline color
glBegin(GL_TRIANGLES);for (int i = 0; i < polyNum; ++i) {for (int j = 0; j < 3; ++j) {glVertex3fv(&polyData[i].Verts[j].Pos.X);}}glEnd();glDepthFunc(GL_LESS);               // ResetglCullFace(GL_BACK);                // ResetglPolygonMode(GL_BACK, GL_FILL);    // Reset
        glDisable(GL_BLEND);}
}
Main.cpp

Thanks for Nehe's tutorials, this is his home.

转载于:https://www.cnblogs.com/clairvoyant/p/5906416.html

这篇关于outdated: 37.Cel-Shading的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/411642

相关文章

Deferred shading技术简介

参考文章:http://blog.sina.com.cn/s/blog_458f871201017i06.html Deferred shading是这样一种技术:将光照/渲染计算推迟到第二步进行计算。我们这样做的目的是为了避免多次(超过1次)渲染同一个像素。 其基本思想如下: 1、在第一步中,我们渲染场景,但是与通常情况下应用反射模型计算片断颜色不同的是,我们只是简单的将几何信息(位置

NYOJ 37 回文字符串(记忆化搜索)

OJ题目 : 戳这里~~ 描述 所谓回文字符串,就是一个字符串,从左到右读和从右到左读是完全一样的,比如"aba"。当然,我们给你的问题不会再简单到判断一个字符串是不是回文字符串。现在要求你,给你一个字符串,可在任意位置添加字符,最少再添加几个字符,可以使这个字符串成为回文字符串。 输入 第一行给出整数N(0<N<100) 接下来的N行,每行一个字符串,每个字符串长度不超过1000.

数据库系统 第37节 数据库快照

数据库快照是一种用于数据保护和恢复的技术,它可以创建数据库在某一特定时间点的完整副本,而不需要停止数据库服务。这种技术对于数据备份、灾难恢复、报告生成和分析等场景非常有用。数据库快照通常可以分为两种类型:行级快照和页级快照。 行级快照: 行级快照在数据库中为每一行数据维护一个版本历史记录。这意味着,当数据被修改时,旧版本的数据不会被立即删除,而是保留在数据库中,直到快照不再需要。这种快照方式允

LeetCode - 37. Sudoku Solver

37. Sudoku Solver  Problem's Link  ---------------------------------------------------------------------------- Mean:  求解数独. analyse: 只是9宫格的数独,而且测试数据都不难,所以可以直接使用递归求解,类似于N-Queue问题. 但如果宫格

leetcode解题思路分析(六)37-42题

解数独 编写一个程序,通过已填充的空格来解决数独问题。 本题主要是采取回溯法解决,选择最少空位的行、列、块,然后进行填入,如果出现问题则回溯 class Solution {public:// line, column, block 分别存储每行、每列、每宫中可用的数字vector<set<int>> line, column, block;//哈希更新每行/列/宫中可以使用的数字void

Java37: 数据库(Oracle)

DB2 Oracle Infomix MySQL Sybase SQLServer 1 什么是数据库     数据需要持久保存     (磁盘文件)  数据库(数据库管理系统)是个软件     安全,可靠,高效    数据库服务器,数据中心  关系型数据库     用表来存储数据的数据库  SQL 通用的关系型数据库的操作语言  不同数据库之间SQL有一定的差异  NoSQL Not o

传输大咖37 | 教育培训行业文件传输难题及解决方案

教育培训行业在文件传输过程中面临着一系列挑战,这些挑战不仅影响了工作效率,也对数据安全构成了潜在威胁。本文将探讨教育培训行业在文件传输方面的痛点,并提出镭速传输系统作为解决方案。 教育培训行业文件传输的痛点 信息孤岛问题:教育机构内部不同部门或校区间信息共享困难,导致资源无法有效利用。 数据安全风险:存储有大量敏感数据,如学生个人信息、成绩等,一旦泄露后果严重。 法规遵从性:需严格

课程37:Docker持久化部署(数据库、日志、配置文件)

🚀前言 本文是《.Net Core从零学习搭建权限管理系统》教程专栏的课程(点击链接,跳转到专栏主页,欢迎订阅,持续更新…) 专栏介绍:以实战为线索,基于.Net 7 + REST + Vue、前后端分离,不依赖任何第三方框架,从零一步一步讲解权限管理系统搭建。 专栏适用于人群:Web后端开发人员 本课程内容: 1、Docker持久化问题 2、VOLUME持久化:Web、Mysql

Rikka with string BC#37

Rikka with string Accepts: 395 Submissions: 2281 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) 问题描述 众所周知,萌萌哒六花不擅长数学,所以勇太给了她一些数学问题做练习,其中有一道是这样的: 有一天勇太得

LeetCode 热题100-37 二叉树的最大深度

二叉树的最大深度 给定一个二叉树 root ,返回其最大深度。 二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。 示例 1: 输入:root = [3,9,20,null,null,15,7]输出:3 示例 2: 输入:root = [1,null,2]输出:2 提示: 树中节点的数量在 [0, 104] 区间内。-100 <= Node.v