C++

1.求给定二叉树的最小深度。最小深度是指树的根结点到最近叶子结点的最短路径上结点的数量。

方法1
层序遍历,它不需要遍历所有的节点,一旦找到一个叶节点,它肯定是最短的。

class Solution {
public:
    typedef TreeNode* tree;
    int run(TreeNode *root) {
        //采用广度优先搜索,或者层序遍历,找到的第一个叶节点的深度即是最浅。
      if(! root) return 0;
      queue<tree> qu;
      tree last,now;
      int level,size;
      last = now = root;
      level = 1;qu.push(root);
      while(qu.size()){
        now = qu.front();
        qu.pop();
        size = qu.size();
        if(now->left)qu.push(now->left);
        if(now->right)qu.push(now->right);
        if(qu.size()-size == 0)break;
        if(last == now){
          level++;
          if(qu.size())last = qu.back();
        }
      }
      return level;
    }
};

方法2
递归,若为空树返回0;
若左子树为空,则返回右子树的最小深度+1;(加1是因为要加上根这一层,下同)
若右子树为空,则返回左子树的最小深度+1;
若左右子树均不为空,则取左、右子树最小深度的较小值,+1;

class Solution {
public:
    int run(TreeNode *root)
    {
        if(root == nullptr) return 0;
        if(root->left == nullptr) // 若左子树为空,则返回右子树的最小深度+1
        {
            return run(root->right)+1;
        }
        if(root->right == nullptr) // 若右子树为空,则返回左子树的最小深度+1
        {
            return run(root->left)+1;
        }
        // 左右子树都不为空时,取较小值
        int leftDepth = run(root->left);
        int rightDepth = run(root->right);
        return (leftDepth<rightDepth)?(leftDepth+1):(rightDepth+1);
    }
};
2.成绩排序
作者:▁▁▁久而久之;
链接:[https://www.nowcoder.com/questionTerminal/0383714a1bb749499050d2e0610418b1](https://www.nowcoder.com/questionTerminal/0383714a1bb749499050d2e0610418b1)
来源:牛客网


#include<iostream>
#include<string>
using namespace std;
int main()
{
    int m, t;
    while (cin >> m >> t)
    {
        int grade; 
        string name;
        string M[101];
        while (m--)//比for循环简洁
        {
            char ch[10];
            cin >> name >> grade;
            itoa(grade,ch,10);
            M[grade] = M[grade] + name + " " + ch + '\n';
        }
        if (t == 1)
        {
            for (int i = 0;i <= 100; ++i)
                if (!M[i].empty()) 
                    cout<<M[i];
        }
        else 
        {
            for (int i = 100; i >= 0; --i)
                if (!M[i].empty()) 
                    cout<<M[i];
        }
    }
 return 0;
}

知识点1:while(cin>>n){}
cin>>a代表获取键盘输入的值赋值给变量a,将cin>>a置于while的循环条件内将会一直测试输入流是否正常。

如果输入流正常,就会继续循环获取键盘值,如果输入流错误,或者达到文件末尾,该循环就会终止。

测试代码如下:

#include<iostream>
using namespace std;

int main()
{
    int a= 0 ;
    int cnt=1;//统计次数
    while(cin >> a)
    {
        cout<<a<<endl;
        cnt++;
    } //while循环结束 
    cout<<cnt<<endl;
    return 0;
}

该代码会将从键盘获取到的标准输入流(即键盘输入的整数)以标准输出流输出(即显示到屏幕终端上)。

知识点2:itoa(grade,ch,10);
VC6.0中,将int转换成string:

#include<iostream>
#include<string>
using namespace std;

int main()
{
    int n=65535;
    char t[256];
    string s;
    sprintf(t,"%d",n);
    s=t;
    cout<<s<<endl;
    return 0;
}
#include<iostream>
#include<string>
#include<sstream>
using namespace std;

int main()
{
    int n=65535;
    stringstream ss;
    string ss;
    ss<<n;//注意箭头方向
    ss>>s;
    cout<<s<<endl;
    return 0;
}

可以这样理解,stringstream(ss)可以吞下不同的类型,根据s的类型,吐出不同的类型。

使用itoa
char *itoa(int value,char *string,int radix);
value:欲转换的数据
string:目标字符串的地址
radix:转换后的进制数
返回值:指向string这个字符串的指针

#include<iostream>
#include<string>
using namespace std;

int main()
{
    int a=30;
    char c[8];
    itoa(a,c,16);
    cout<<c<<endl;//1e
    return 0;
}

注意:itoa并不是一个标准的C函数,它是Windows特有的,如果要写跨平台的程序,请用sprintf

3.约数个数

输入描述:
输入的第一行为N,即数组的个数(N<=1000)
接下来的1行包括N个整数,其中每个数的范围为(1<=Num<=1000000000)
当N=0时输入结束。
输出描述:
可能有多组输入数据,对于每组输入数据,
输出N行,其中每一行对应上面的一个数的约数的个数。

#include<iostream>
#include<vector>
using namespace std;

void Yueshu(long int p[])
{
    long int a[1000]={0};
    long int count=0;
    long int j=0;
    while(*p!=0)
    {
        a[count]=*p;
        p=p+1;
        count++;
    }
    
    while(a[j]!=0)
    {
        long int ans = 0;
        long int l;
        for (l = 1; l*l<a[j]; l++)
        {
            if (a[j]%l == 0)
                ans += 2;
        }
        if (l*l == a[j]) ans++;
        cout<<ans<<endl;
        j++;
    }
}

int main()
{
    int N;
    long int num[1000]={0};
    while(cin>>N)
    {
        if(N==0) return 0;
        for(int i=0;i<N;i++)
            cin>>num[i];
        Yueshu(num);
    }
    return 0;
}    

知识点1:
如果用普通的遍历求约数的方法,时间复杂度会超。
用以下的方法求约数可以降低时间复杂度

int ans = 0; 
int l;
for (l = 1; l*l<a[j]; l++)
{
    if (a[j]%l == 0)
        ans += 2;
}
if (l*l == a[j]) 
    ans++;
return ans;

知识点2:
数组作为参数传递的时候,会自动退化为指向数组首地址的指针。形参为相应的指针形式,用*访问数组元素。
void Test(int p[])
void Test(int *p)
p=p+1访问下一个元素。

4.代理服务器

使用代理服务器能够在一定程度上隐藏客户端信息,从而保护用户在互联网上的隐私。我们知道n个代理服务器的IP地址,现在要用它们去访问m个服务器。这 m 个服务器的 IP 地址和访问顺序也已经给出。系统在同一时刻只能使用一个代理服务器,并要求不能用代理服务器去访问和它 IP地址相同的服务器(不然客户端信息很有可能就会被泄露)。在这样的条件下,找到一种使用代理服务器的方案,使得代理服务器切换的次数尽可能得少。

输入描述:
每个测试数据包括 n + m + 2 行。
第 1 行只包含一个整数 n,表示代理服务器的个数。
第 2行至第n + 1行每行是一个字符串,表示代理服务器的 IP地址。这n个 IP地址两两不相同。
第 n + 2 行只包含一个整数 m,表示要访问的服务器的个数。
第 n + 3 行至第 n + m + 2 行每行是一个字符串,表示要访问的服务器的 IP 地址,按照访问的顺序给出。
每个字符串都是合法的IP地址,形式为“xxx.yyy.zzz.www”,其中任何一部分均是0–255之间的整数。输入数据的任何一行都不包含空格字符。
其中,1<=n<=1000,1<=m<=5000。

输出描述:
可能有多组测试数据,对于每组输入数据, 输出数据只有一行,包含一个整数s,表示按照要求访问服务器的过程中切换代理服务器的最少次数。第一次使用的代理服务器不计入切换次数中。若没有符合要求的安排方式,则输出-1。

示例
输入
3
166.111.4.100
162.105.131.113
202.112.128.69
6
72.14.235.104
166.111.4.100
207.46.19.190
202.112.128.69
162.105.131.113
118.214.226.52
输出
1

服务器中寻找初次出现最晚的代理服务器的IP地址,为第一次切换。
以当前位置为新的起点,再次在服务器中开始寻找所有的代理服务器的出现最晚的IP地址,为下一次切换。
循环往复,直到遍历完所有服务器

#include<iostream>
#include<string>
using namespace std;

int main()
{
    int N,M;
    string n[1000];
    string m[5000];
    while(cin>>N)
    {
        for(int i=0;i<N;i++)
            cin>>n[i];
        cin>>M;//这里不用加while()
        for(int k=0;k<M;k++)
            cin>>m[k];
      
        //唯一不可行的时候:只有一个代理服务器,且服务器有IP相同的
        if(N==1)
        {
            int f=1;
            for(int t=0;t<M;t++)
                if(n[0]==m[t])
                    f=0;
            if(f)
                cout<<0<<endl;
            else
                cout<<-1<<endl;
         continue;
        }
        
        int max=0;//选择初次出现最晚的代理IP作为切换的新IP
        int begin=0;//断点
        int count=0;
        int j,i;
        while(begin!=M)
        {
            for(i=0;i<N;i++)
            {
                for(j=begin;j<M;j++)
                {
                    if(n[i]==m[j])
                        break;
               
                }
                if(j>max)
                    max=j;
            }
            begin=max;
            count++;
        }
        cout<<count-1<<endl;//第一次设置不算在内
    }
    return 0;
}

Tips:没有较为陌生的语法,掌握好思路。

5.手机键盘

按照手机键盘输入字母的方式,计算所花费的时间 如:a,b,c都在“1”键上,输入a只需要按一次,输入c需要连续按三次。 如果连续两个字符不在同一个按键上,则可直接按,如:ad需要按两下,kz需要按6下 如果连续两字符在同一个按键上,则两个按键之间需要等一段时间,如ac,在按了a之后,需要等一会儿才能按c。 现在假设每按一次需要花费一个时间段,等待时间需要花费两个时间段。 现在给出一串字符,需要计算出它所需要花费的时间。

一个很好的思路

一个数组用key[]顺序记录26个字母按键次数.
然后判断两个字母是否在同一个按键上 : 如果在同一个按键上,那么下标差(字母间距)就等于按键次数差。

#include<iostream>
#include<string>
using namespace std;
int main()
{
    int key[26] = {1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,4,1,2,3,1,2,3,4};
    string str;
    while(cin>>str)
    {
        int count = key[str[0]-'a'];
        for(int i=1;i<str.size();++i)
        {
            count += key[str[i]-'a'];
            if(key[str[i]-'a']-key[str[i-1]-'a']==str[i]-str[i-1])//判断是否在同一个按键上
                count+=2;
        }
        cout<<count<<endl;
    }
}
6.求质因数的个数

求正整数N(N>1)的质因数的个数。 相同的质因数需要重复计算。如120=22235,共有5个质因数。

下面是我的代码,时间复杂度较高,未能通过:

#include<iostream>
using namespace std;

int Zhi(long int a)
{
    if(a==2) 
        return 1;
    else
        for(long int i=2;i<a;i++)
            if(a%i==0) 
                return 0;
    return 1;
}

int main()
{
    long int num;
    while(cin>>num)
    {
        long int count=0;
        //如果输入质数,质因数个数为0;
        if(Zhi(num))
        {
            cout<<0<<endl;
            continue;
        }

        long int k=2;
        while(k<=num)
        {
            if(num%k==0)
            {
                if(Zhi(k))
                    count++;
                num=num/k;
                k=2;
                continue;
            }
            k++;    
        }
        cout<<count<<endl;
    }
    return 0;
}

N最多只存在一个大于sqrt(N)的质因数,所以只需要把所有小于此范围的质数去除后,剩余的就是大于的了。因此在不断除以质数后,如果N还大于1,说明还有且仅有1个大于sqrt(N)的质因数。

#include <iostream>
#include <cmath>
using namespace std;
int main(){
    //这题的关键:
    //1、是sqrt,可以极大减少复杂度,若是到方根N仍大于1,则必还有且只还有1个质因数
    //2、每次瞬间整除都可帮助减少遍历范围
    long M=100;
    while(cin>>M)
    {
        long count=0;
            for(long j=2;j<=sqrt(M);j++)
            {
             while(M%j==0)
             {
                 M=M/j;
                 count++;
             }
             if(M<=1)break;
            }
        if(M>1)count++;
        cout<<count<<endl;
    }  
    return 0;
}

Q:为什么不用判断j是不是质数呢?

因为任何一个合数都能被一个比它小的质数整除。所以当我们用小质数去分解这个给定的数时,我们已经把他的合数因子分解了。
或者从反面去说,如果出现了一个合数a能整除这个数M,那显然在j =a之前应该有一个质数p < a 能把a整除,而之前反复地用M去除以p直到p不能再整除M 程序才往下执行,那怎么会后来又出现了M中一个合数因子a能被p整除呢?这显然矛盾了。
从而可以推出,程序中能整除M的数都是质数。

7.整数分解

一个整数总可以拆分为2的幂的和,例如: 7=1+2+4 7=1+2+2+2 7=1+1+1+4 7=1+1+1+2+2 7=1+1+1+1+1+2 7=1+1+1+1+1+1+1 总共有六种不同的拆分方式。 再比如:4可以拆分成:4 = 4,4 = 1 + 1 + 1 + 1,4 = 2 + 2,4=1+1+2。 用f(n)表示n的不同拆分的种数,例如f(7)=6. 要求编写程序,读入n(不超过1000000),输出f(n)%1000000000。

#include <iostream>
#include <vector>
using namespace std;
 
/*
思路:
1、奇数:f(5)的分解方法为f(4) + 1,1不可再分,f(n) = f(n - 1)
2、偶数:f(4)的分解方法为2 + 1 + 1或2 + 2, f(n) = f(n - 2) + f(n / 2)
*/
 
int main() {
    long long n;
    while (cin >> n) {
        vector<long long> nums(n + 1);
        nums[1] = 1;
        nums[2] = 2;
 
        for (int i = 3; i <= n; i++) {
            if (i % 2 == 1) {
                nums[i] = nums[i - 1] % 1000000000;
            }
            else {
                nums[i] = (nums[i - 2] + nums[i / 2]) % 1000000000;
            }
        }
 
        cout << nums[n] << endl;
    }
    return 0;
}

理解无能,且先记下来。
据说是背包问题的变形。
对应的代码:

#include<iostream>
#include<cmath>
using namespace std;
const int MAXLENGTH=10000001;
int F[MAXLENGTH]; 
int main(){
    int V; 
    int Ci[21];
    F[0]=1;
    for(int i=1;i<=20;i++){
        Ci[i]=(int)pow(2,i-1);
    }
    while(cin>>V){
        for(int i=1;i<=20;i++){
            for(int j=Ci[i];j<=V;j++){
                F[j]=(F[j]+F[j-Ci[i]])%1000000000;
            }
        }
        cout<<F[V]<<endl;
    }
    return 0;
}
8.成绩排序

输入描述:
输入第一行包括一个整数N(1<=N<=100),代表学生的个数。
接下来的N行每行包括两个整数p和q,分别代表每个学生的学号和成绩。
输出描述:
按照学生的成绩从小到大进行排序,并将排序后的学生信息打印出来。
如果学生的成绩相同,则按照学号的大小进行从小到大排序。

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
struct student
{
    int num;
    int score;
};
bool cmp(const student& a,const student b)
{
    if(a.score<b.score)
        return true;
    else if(a.score==b.score&&a.num<b.num)
        return true;
    return false;
}
int main()
{
    int n;
    cin>>n;
    vector<student> table(n);
    for(int i=0;i<n;i++)
        cin>>table[i].num>>table[i].score;
    sort(table.begin(),table.end(),cmp);
    for(i=0;i<n;i++)
        cout<<table[i].num<<" "<<table[i].score<<endl;
    return 0;
}

知识点1:

在VC6.0中,数组不可以用变量初始化,但容器可以。

知识点2:

STL的使用

9.二叉树遍历

编一个程序,读入用户输入的一串先序遍历字符串,根据此字符串建立一个二叉树(以指针方式存储)。 例如如下的先序遍历字符串: ABC##DE#G##F### 其中“#”表示的是空格,空格字符代表空树。建立起此二叉树以后,再对二叉树进行中序遍历,输出遍历结果。

输入
abc##de#g##f###
输出
c b e g d f a

//这个实际上就是树的遍历的非递归实现,入栈时访问 = 前序, 出栈时访问 = 中序
#include <iostream>
#include <string>
#include <stack>
using namespace std;
int main()
{  
    string pre;  
    while(cin >> pre)
    {
        stack<char> s;
        for(auto it : pre){
            if(it != '#')
                s.push(it);
            else{
                if(!s.empty()){
                    cout << s.top() << ' ';
                    s.pop();
                }
            }
        }
        cout << '\n';  }
}
  • auto it:pre在VC6.0上不能通过编译,调整如下。
#include<iostream>
#include<string>
#include<stack>
using namespace std;

int main()
{
    string str;
    stack<char> s;
    while(cin>>str)
    {
        for(int i=0;str[i]!='\0';i++)
        {
            if(str[i]!='#')
                s.push(str[i]);
            else
            {
                if(!s.empty())
                {
                    cout<<s.top()<<" ";
                    s.pop();
                }
            }
        }
        cout<<endl;
    }
    return 0;
}
10.BFS(广度优先搜索)

玛雅人有一种密码,如果字符串中出现连续的2012四个数字就能解开密码。给一个长度为N的字符串,(2=<N<=13)该字符串中只含有0,1,2三种数字,问这个字符串要移位几次才能解开密码,每次只能移动相邻的两个数字。例如02120经过一次移位,可以得到20120,01220,02210,02102,其中20120符合要求,因此输出为1.如果无论移位多少次都解不开密码,输出-1。

典型的BFS,节点就是一个字符串,与它相邻的节点就是由它交换一次所得的字符串。
从初始节点出发,看看它交换一次形成的字符串里哪些没出现过,这些字符串如果有符合要求的就结束BFS返回结果,如果不符合要求那就把它们加入队列。遍历完之后还是没碰到符合要求的字符串就返回-1。

#include<iostream>
#include<queue>
#include<string>
#include<map>
 
using namespace std;
map<string,int> M; //用来记录交换了多少次位置
queue<string> Q; //广度优先时,用来存储字符串
 
string swap(string str,int i)
{
    char temp = str[i];
    str[i] = str[i+1];
    str[i+1] = temp;
 
    return str;
}
 
int BFS(string str)
{
    string newStr;
    M.clear(); //清空map
 
    //清空队列
    while(!Q.empty())
    {
        Q.pop();
    }
 
    Q.push(str);//将字符串加入队列
    M[str] = 0; //str作为根节点,高度为0
 
    while(!Q.empty())
    {
        str = Q.front();//将队列的第一个值赋给str
        Q.pop();
 
        //交换str中相邻的两个字符
        for(int i=0;i<str.length()-1;i++)
        {
            newStr = swap(str,i);
 
            if(M.find(newStr) == M.end())//如果该字符串未出现过,说明该字符串是交换过后的字符串
            {
                M[newStr] = M[str]+1;//交换次数+1
                if(newStr.find("2012",0) != string::npos)//从该字符串中找到了2012,返回交换次数
                {
                    return M[newStr];
                }
                else
                {
                    Q.push(newStr);//如果不符合要求,则继续进行交换
                }
                 
            }
        }
    }
 
    return -1;//未找到
}
 
int main()
{
    int length;
    string s;
 
    while(cin >> length)
    {
        cin >> s;
        if(length < 4)
        {
            cout << "-1" << endl;
        }
        if(s.find("2012",0) != string::npos)//如果字符串中有2012,直接输出交换0次
        {
            cout << "0" << endl;
        }
        else
        {
            cout << BFS(s) << endl;
        }
         
    }
 
    return 0;
}
11.求最大最小值

输入N个(N<=10000)数字,求出这N个数字中的最大值和最小值。每个数字的绝对值不大于1000000。

本题较为简单,复习sort()的使用。

#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;

int main()
{
    int N;
    while(cin>>N)
    {
        vector<long int> a(N);
        for(int i=0;i<N;i++)
            cin>>a[i];
        sort(a.begin(),a.end());
        cout<<a[N-1]<<" "<<a[0]<<endl;
    }
    return 0;
}
(未解决)12.最少邮票数

有若干张邮票,要求从中选取最少的邮票张数凑成一个给定的总值。 如,有1分,3分,3分,3分,4分五张邮票,要求凑成10分,则使用3张邮票:3分、3分、4分即可。
输入描述:
有多组数据,对于每组数据,首先是要求凑成的邮票总值M,M<100。然后是一个数N,N〈20,表示有N张邮票。接下来是N个正整数,分别表示这N张邮票的面值,且以升序排列。

0-1背包问题/动态规划

0-1最小背包问题 求解装满背包的前提下使用物品最少的数量
其中:
邮票总值相当于背包容量,
邮票的面值相当于物品的重量,
邮票的数量相当于物品的总价值,
每张邮票的价值默认为1。

#include <bits/stdc++.h>
using namespace std;
const int MAX = 0x7f7f7f;
int ZeroOnePack(int nPackCap, int nItemNum, vector<int> &weight)
{
    vector<int> dp(nPackCap+1, MAX);
    dp[0] = 0;
    for (int i = 0; i < nItemNum; ++i)
    {
        int nWeight = weight[i];
        for (int j = nPackCap; j >= nWeight; --j)
        {
            dp[j] = min(dp[j], dp[j-nWeight]+1);
        }
    }
    return dp[nPackCap] < MAX ? dp[nPackCap] : 0;
}
int main()
{
    int M = 0;
    int N = 0;
    while (cin >> M >> N)
    {
        vector<int> weight(N);
        for (int i = 0; i < N; ++i)
        {
            cin >> weight[i];
        }
        cout << ZeroOnePack(M, N, weight) << endl;
    }
    return 0;
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,732评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,496评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,264评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,807评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,806评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,675评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,029评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,683评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,704评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,666评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,773评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,413评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,016评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,204评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,083评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,503评论 2 343

推荐阅读更多精彩内容